/************************************************************************
**
**	Dinero III Cache Simulator 
**	$Header: /var/home/markhill/DistributeDineroIII/RCS/global.h,v 3.3 89/05/04 09:55:48 markhill Exp $
**	Similar to Version 3.1, Released 8/7/85
**
**	Mark D. Hill
**	Computer Sciences Dept.
**	Univ. of Wisconsin
**	Madison, WI 53706
**	markhill@cs.wisc.edu
**
**	Developed DineroIII While Affiliated With:
**
**	Computer Science Division
**	University of California
**	Berkeley, California 94720
**
**	Source File:	global.h
**
************************************************************************/

/* 
**  Copyright 1985, 1989 Mark D. Hill
**
**  Permission to use, copy, modify, and distribute this
**  software and its documentation for any purpose and without
**  fee is hereby granted, provided that the above copyright
**  notice appear in all copies.  Mark D. Hill makes no
**  representations about the suitability of this software
**  for any purpose.  It is provided "as is" without expressed
**  or implied warranty.
*/  

/* for debugging purposes */

#define test 0

/*  for 370 port:
370
370	Activate "define IBM370;" deactivate "define NOTIBM370."
370	"Ifdef's" will realize changes in the rest of the program.
370
*/
#define NOTIBM370
/*	#define IBM370	*/

/*	Enable fast, implemenation-dependent input character 
**	interpretation.  Comment-out "define" to disable.
*/
#define FAST_BUT_DANGEROUS_INPUT

#include <stdio.h>
#include <limits.h>

#ifndef LONG_MAX
#define LONG_MAX INT_MAX
#endif

/*
**	Make global variables declarations just "extern" declarations
**	as long as PUBLIC is not defined. File "main.c" will define
**	PUBLIC to be null before including this file so that the 
**	global variables are declared once and only once.
*/	
#ifndef PUBLIC
#define PUBLIC extern
#endif

/* 
**	Global flags 
*/
#define OK		0
#define	ERR		1
#define ILLEGAL 	'?'
#define ILLEGALNUM 	-1

/*
**	Major structures of data structure 
*/
/*
**	CACHE
*/
typedef struct cachetype {		/* CACHE holds cache parameters */
	int blocksize;                  /* block size in bytes (one cache line) */
	int subblocksize;               /* sub block size in bytes */
	int transfersize;               /* the number of bytes to transfer between the cache and a lower level memory */
	int Usize;                      /* unified cache size in bytes */
	int Isize;                      /* instruction cache size in bytes (if unified cache is not used) */
	int Dsize;                      /* data cache size in bytes (if unified cache is not used) */
	int assoc;                      /* the associativity of the caches (n-way) */
	int numIsets;                   /* the number of sets in the instruction cache */
	int numUorDsets;                /* the number of sets in the data/unified cache */
	int numsets;                    /* the total number of sets in all the defined caches */
	int prefetchdisplacement;
        int wordsize;                   /* data word size in bytes */
        int buswidth;                   /* bus width in bytes that connects the cache with a lower level memory */
} CACHETYPE;
#define MAXNUMSUBBLOCKS	 32	/* Number of bits in an "int." */

/*
**	POLICY
*/
typedef struct policytype {		/* POLICY holds policies */
	char replacement;
	char fetch;
	int  prefetchdist;
	int  abortprefetchpercent;
	char write;
	char writeallocate;
} POLICYTYPE;
#define LRU		'l'	/* replacement policies */
#define FIFO		'f'
#define RANDOM		'r'

#define DEMAND		'd'	/* fetch policies */
#define ALWAYSPREFETCH	'a'
#define LOADFORWARDPREFETCH 'l'
#define SUBBLOCKPREFETCH 'S'
#define MISSPREFETCH 	 'm'
#define TAGGEDPREFETCH   't'


#define WRITETHROUGH	'w'	/* write policies */
#define COPYBACK	'c'
#define NOWRITEALLOCATE	'n'
#define WRITEALLOCATE	'w'

#define MAXINTPERCENT (int) (INT_MAX/100)

/*
** 	CTRL
*/
typedef struct ctrltype {		/* CTRL holds flags to turn       */
					/* control options on and off     */
	int debug;
	int output;
	long skipcount;
	long maxcount;
	long tracecount;
	long Q;

#define MAXCOUNT 10000000                /* @@ put here instead of in "cmdarg.c". Should NOT exceed LONG_MAX !!! */


/*  for 370 port:
370
370	Must do file I/O on 3081. We will read is first word
370	of filename and append "DIN."
370
*/
#ifdef IBM370
#define MAXNAMELENGTH 84
	char infilename[MAXNAMELENGTH];	/* Input file name */
	FILE *infilep;			/* Input file pointer */
#endif
} CTRLTYPE;

#define NODEBUG		0	/* Debug options */
#define DEBUG1		1
#define DEBUG2		2

#define TERSE		0	/* Output options */
#define VERBOSE		1
#define BUS		2
#define BUS_SNOOP	3
/*
**	METRIC
*/
#define NUMACCESSTYPES	6
#define PREFETCH	10
typedef struct metrictype {		/* METRIC holds cache performance */
					/* numbers			  */
	int fetch[PREFETCH+NUMACCESSTYPES];
	int miss[PREFETCH+NUMACCESSTYPES];
	int blockmiss[PREFETCH+NUMACCESSTYPES];
	long int bus_traffic_in;   /* number of bytes coming into the cache from the lower level memory */
	long int bus_traffic_out;  /* number of bytes going to the lower level memory */
        long int bus_transactions_initiated; /* number of bus transactions that were initiated (bursts) */
        long int bus_usage;                  /* number of times the bus carried data (can be several cycles per transaction if the bus width is smaller than the (sub-)block size. */
	int Icount;
	int Rcount;
} METRICTYPE;
#define	BUSREAD		'r'
#define BUSWRITE	'w'
#define BUSPREFETCH	'p'
#define BUSSNOOP	's'

/* 
** Internal Accesstypes
**
** E.g. fetch[2] holds the number of instrn demand fetches,
** and fetch[12] holds the number of instrn prefetch fetches.
*/
#define	XREAD		0
#define	XWRITE		1
#define	XINSTRN		2
#define XMISC		3
#define	XFLUSH		4

#define DEMANDFETCHP(type)	((type) < PREFETCH)

/*
**	DAP
*/
typedef struct decodedaddrtype {	/* DECODEADDR is the type used   */
	long int address;		/* to pass around analyzed addrs @@ changed from int to long int */
	long int blockaddr;             /* block address with all LSB zeroes @@ changed from int to long int */
	int accesstype;
        long int tag;                   /* @@ changed from int to long int */
	int set;                        /* the set the address is mapped to */
	int block;                      /* the byte in the block that the address is mapped to */
	int subblocknum;                /* the number of the sub block that the address is mapped to */
        int validbit;                   /* valid "bit" for each sub-block. If there are no sub-blocks, validbit=1; otherwise, equals 1<<subblocknum. */
                                        /* In any other case, validbit equals 2^subblocknum. */
} DECODEDADDRTYPE;

/*
**	STACKNODE: stack[i] is is priority stack for i-th set.
*/
typedef struct stacknodetype {		/* STACKNODE is the type used for nodes in priority stacks */
	long int tag;			/* @@ changed from int to long int */
	long int blockaddr;		/* @@ changed from int to long int */
	int valid;
	int reference;
	int dirty;
	struct stacknodetype *next;
} STACKNODETYPE;
#define SIZEOFSTACKNODETYPE	sizeof(STACKNODETYPE)
#define VALID		1
#define NOTVALID	0
#define LOWVALIDMASK    0x00000001
#define NOTREFERENCED   0
#define NOTDIRTY   0
#define LOWDIRTYMASK    0x00000001

/* #define BUFFERSIZE	64 */		/* num of elements in malloc buffer */
/* #define FREETHRESHOLD	64 */	/* Number to free at a time */
/* Modified to save space for simlating large caches */
#define BUFFERSIZE	4096		/* num of elements in malloc buffer */
#define FREETHRESHOLD	8		/* Number to free at a time */



/*
** 	Addresses are read first from this stack and then from the
**	input trace.  This stack is used for prefetch address and
**	(maybe) for virtual memory translation.
*/
typedef struct addrstacktype {
	int label;
	long int address;  /* @@ changed from int to long int */
 } ADDRSTACKTYPE;
#define MAXNUMADDRSTACK	65

/*
**	GLOBAL VARIABLES
*/
PUBLIC int bufferindex;			/* global index to buffer */
PUBLIC int numnodes;			/* Count on storage allocated */
PUBLIC STACKNODETYPE freelist;		/* List head for free list */
PUBLIC STACKNODETYPE *stack;		/* global ptr to top of stacks */

PUBLIC ADDRSTACKTYPE addrstack[MAXNUMADDRSTACK]; /* addr of be processed */
PUBLIC int size_addrstack;

