/************************************************************************
**
**	Dinero III Cache Simulator 
**	$Header: /var/home/markhill/DistributeDineroIII/RCS/init.c,v 3.3 89/05/04 09:57:34 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:	init.c
**
************************************************************************/

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

#include "global.h"

init(argc,argv,			/* Initialize. */
		cachep,policyp,ctrlp,metricp)
int argc;			/* <  */
char *argv[];			/* <  */
CACHETYPE *cachep;		/* <> */
POLICYTYPE *policyp;		/* <> */
CTRLTYPE *ctrlp;		/* <> */
METRICTYPE *metricp;		/* <> */
/* returns: OK
*/

{
extern int getcmdargs();
extern int echocmdargs();

int flag;
/*
**	Get command line arguments and echo them. Illegal entries
**	cause premature termination.
*/
flag = getcmdargs(argc,argv,cachep,policyp,ctrlp);
echocmdargs(cachep,policyp,ctrlp);

if (flag != OK) {		/* premature termination */
	printf("\n---Execution prematurely terminated.\n");
	exit(ERR);
 }
/*
**	Initialize
*/
initmisc(cachep,policyp,ctrlp);	/* Init "set" params. */
initstacks(cachep);		/* Init priority stacks */
initmetric(metricp);		/* Init measurement stuff */

} /* ****************************************************************** */



initmisc(cachep,policyp,ctrlp)          /* Set up "set" params. */
CACHETYPE *cachep;              /* <>  */
POLICYTYPE *policyp;            /* <  */
CTRLTYPE *ctrlp;                /* <>  */
/* affects: Cachep->numIsets,numUorDsets,numsets.
** returns: OK
*/
{
#ifdef IBM370
extern int readfrominputstream370();
#else
extern int readfrominputstream();
#endif
extern int init_addrstack();
int theblocksize;
int label,addr;

/*  for 370 port:
370
370	Must do file I/O on 3081.
*/
#ifdef IBM370
ctrlp->infilep = fopen(ctrlp->infilename, "r");
#endif

theblocksize = cachep->blocksize;

if (cachep->Isize > 0) { /* I-Cache */
	cachep->numIsets = ( cachep->Isize / theblocksize) / cachep->assoc;
 }
else { /* No I-Cache */
cachep->numIsets = 0;
 }

if (cachep->Dsize > 0) { /* D-Cache */
	cachep->numUorDsets = ( cachep->Dsize / theblocksize) / cachep->assoc;
 }
else { /* U-Cache */
	cachep->numUorDsets = ( cachep->Usize / theblocksize) / cachep->assoc;
 }
cachep->numsets = cachep->numIsets + cachep->numUorDsets;

/*
**	Compute transfersize & prefetch displacement
**	policyp->prefetchdist is in (sub)-blocks whereas
**	cachep->prefetchdisplacement is in bytes.
*/
if (cachep->subblocksize==0) {
	cachep->transfersize = cachep->blocksize * policyp->prefetchdist;
 }
else {
	cachep->transfersize = cachep->subblocksize * policyp->prefetchdist;
 }

cachep->prefetchdisplacement = cachep->transfersize * policyp->prefetchdist;

/*
**	Initialize addrstack
*/
init_addrstack();

/*
**	Skip over trace addresses?
*/
ctrlp->tracecount = 0 - ctrlp->skipcount;

while (ctrlp->tracecount < 0) {
/*  for 370 port:
370
370	Must do file I/O on 3081.
*/
#ifdef IBM370
		readfrominputstream370(&label,&addr,ctrlp,ctrlp->infilep);
#else
		readfrominputstream(&label,&addr,ctrlp);
#endif
 }

} /* ****************************************************************** */



initstacks(cachep)			/* Set up priority stacks */
register CACHETYPE *cachep;		/* <  */
/* affects: stack, stack[i].tag,aux,next, 
	    freelist.tag,aux,next, & bufferindex 
** returns: OK
*/
/*
**	WARNING: stack, etc. are GLOBAL variables.
*/
{
extern char *calloc();
extern STACKNODETYPE *stack;	/* global ptr to top of stacks */
extern int bufferindex;		/* global index to buffer */
extern STACKNODETYPE freelist;	/* List head for free list */
extern int numnodes;		/* Count on storage allocated */
register int i;
register int numberofsets;

unsigned int unsignednumofsets;

numberofsets = cachep->numsets;
/*
**	Get block for top of stacks. "stack" is a global variable.
*/
/* stack = (STACKNODETYPE *)malloc((numberofsets)*sizeof(STACKNODETYPE)); */

unsignednumofsets = numberofsets;
stack = (STACKNODETYPE *)calloc(unsignednumofsets,SIZEOFSTACKNODETYPE);

/*
**	Zero TOSs.
*/
for (i=0; i<numberofsets; i++) {
	stack[i].tag = 0;
	stack[i].next = NULL;
 }
/*
**	Zero freelist; init bufferindex
*/
freelist.tag = 0;
freelist.next = NULL;
bufferindex = BUFFERSIZE;
numnodes = 0;

} /* ****************************************************************** */



initmetric(metricp)		/* Init performance variables */
METRICTYPE *metricp;			/* <> */
/* affects: 
** returns: OK
*/
{
int i;

metricp->Icount = 0;
metricp->Rcount = 0;
metricp->bus_traffic_in = 0;
metricp->bus_traffic_out = 0;
metricp->bus_transactions_initiated = 0;
metricp->bus_usage = 0;

for (i=0; i<(PREFETCH+NUMACCESSTYPES); i++) {
	metricp->fetch[i] = metricp->miss[i] = metricp->blockmiss[i] = 0;
 }

} /* ****************************************************************** */

