/* This example code can be used to measure MMR latency for different peripheral registers defined in "registers.dat" file */
#include "MMR_Latency_Core1.h"
#include <sys/platform.h>
#include "adi_initialize.h"
#include "stdio.h"
#include <xtensa/xtruntime.h>
void spu_init(void);
/**
 * If you want to use command program arguments, then place them in the following string.
 */
char __argv_string[] = "";

volatile clock_t clock_start;
volatile clock_t clock_stop;
volatile clock_t cycles;
volatile clock_t cycles_offset;
volatile clock_t cycles_offset1;
volatile clock_t cycles_offsetn;
volatile clock_t clock_start1;
volatile clock_t clock_stop1;
volatile clock_t clock_startn;
volatile clock_t clock_stopn;
volatile uint32_t* pRegisterArray[]=
{
	#include "registers.dat"
};

clock_t cycle_start;
clock_t cycle_stop;
int cycles_write;
int cycles_read;
uint32_t exc_cause;
uint8_t cause, type, subtype, LSFO;

void read_exc_cause(ExcFrame *ef)
{
	/*Read EXCCAUSE register*/
	exc_cause = ef->exccause;
	cause	= (exc_cause & EXCCAUSE_CAUSE_MASK) >> EXCCAUSE_CAUSE_SHIFT;
	type	= (exc_cause & EXCCAUSE_TYPE_MASK) >> EXCCAUSE_TYPE_SHIFT;
	subtype	= (exc_cause & EXCCAUSE_SUBTYPE_MASK) >> EXCCAUSE_SUBTYPE_SHIFT;
	LSFO	= (exc_cause & EXCCAUSE_LSFO_MASK) >> EXCCAUSE_LSFO_SHIFT;
	printf(" Cause   = %d\n Type    = %d\n Subtype = %d\n LSFO    = %d\n", cause, type, subtype, LSFO);
}

void ExcHandler(void *arg)

{
	printf("In exception handler\n");
   ExcFrame *ef = (ExcFrame *) arg;
	read_exc_cause(ef);
	ef->pc += 3;		// Move PC past instruction that raised exception

}

int main(int argc, char *argv[])
{
	adi_initComponents();

	xtos_set_exception_handler(EXCCAUSE_INSTRUCTION, ExcHandler, NULL);
		xtos_set_exception_handler(EXCCAUSE_ADDRESS, ExcHandler, NULL);
		xtos_set_exception_handler(EXCCAUSE_DEBUG, ExcHandler, NULL);
		xtos_set_exception_handler(EXCCAUSE_SYSCALL, ExcHandler, NULL);
		xtos_set_exception_handler(EXCCAUSE_MEMORY, ExcHandler, NULL);
		xtos_set_exception_handler(EXCCAUSE_EXTERNAL, ExcHandler, NULL);
		xtos_set_exception_handler(EXCCAUSE_HARDWARE, ExcHandler, NULL);
		xtos_set_exception_handler(EXCCAUSE_CP_DISABLED, ExcHandler, NULL);

	spu_init();

	 clock_startn=clock();
    clock_stopn=clock();
	 cycles_offsetn=clock_stopn-clock_startn;

	int final_count1,start_count1,final_count2,start_count2,temp;
	const int total_registers = (int)(sizeof(pRegisterArray) / sizeof(pRegisterArray[0]));


	for(int i=0; i<total_registers; i++)
	{
		uintptr_t reg_addr = (uintptr_t)pRegisterArray[i];

		if ((reg_addr == (uintptr_t)pREG_TWI0_CLKDIV) || (reg_addr == (uintptr_t)pREG_TWI1_CLKDIV))
		{
			volatile uint16_t *pReg16 = (volatile uint16_t *)reg_addr;
			uint16_t temp16 = *pReg16;

			clock_start=clock();
				*pReg16 = temp16;
				asm("isync;");

				clock_stop=clock();
				cycles_offset=clock_stop-clock_start;

				 clock_start1=clock();
				temp = *pReg16;
				 clock_stop1=clock();
				 cycles_offset1=clock_stop-clock_start;
		}
		else
		{
			temp = *pRegisterArray[i];

			clock_start=clock();
				*pRegisterArray[i]=temp;
				asm("isync;");
				//asm("dsync;");
				clock_stop=clock();
				cycles_offset=clock_stop-clock_start;

				 clock_start1=clock();
				temp = *pRegisterArray[i] ;
				 clock_stop1=clock();
				cycles_offset1=clock_stop-clock_start;
		}
		printf("\n\nRegister Number=%d, Register address=0x%x", i, pRegisterArray[i]);
		printf("\nWrite Cycles=%ld, Read Cycles=%ld", cycles_offset-cycles_offsetn, cycles_offset1-cycles_offsetn);

	}

	return 0;
}

void spu_init(void)
{
*pREG_SPU0_SECUREP0	=	0x3;
*pREG_SPU0_SECUREP1	=	0x3;
*pREG_SPU0_SECUREP2	=	0x3;
*pREG_SPU0_SECUREP3	=	0x3;
*pREG_SPU0_SECUREP4	=	0x3;
*pREG_SPU0_SECUREP5	=	0x3;
*pREG_SPU0_SECUREP6	=	0x3;
*pREG_SPU0_SECUREP7	=	0x3;
*pREG_SPU0_SECUREP8	=	0x3;
*pREG_SPU0_SECUREP9	=	0x3;
*pREG_SPU0_SECUREP10	=	0x3;
*pREG_SPU0_SECUREP11	=	0x3;
*pREG_SPU0_SECUREP12	=	0x3;
*pREG_SPU0_SECUREP13	=	0x3;
*pREG_SPU0_SECUREP14	=	0x3;
*pREG_SPU0_SECUREP15	=	0x3;
*pREG_SPU0_SECUREP16	=	0x3;
*pREG_SPU0_SECUREP17	=	0x3;
*pREG_SPU0_SECUREP18	=	0x3;
*pREG_SPU0_SECUREP19	=	0x3;
*pREG_SPU0_SECUREP20	=	0x3;
*pREG_SPU0_SECUREP21	=	0x3;
*pREG_SPU0_SECUREP22	=	0x3;
*pREG_SPU0_SECUREP23	=	0x3;
*pREG_SPU0_SECUREP24	=	0x3;
*pREG_SPU0_SECUREP25	=	0x3;
*pREG_SPU0_SECUREP26	=	0x3;
*pREG_SPU0_SECUREP27	=	0x3;
*pREG_SPU0_SECUREP28	=	0x3;
*pREG_SPU0_SECUREP29	=	0x3;
*pREG_SPU0_SECUREP30	=	0x3;
*pREG_SPU0_SECUREP31	=	0x3;
*pREG_SPU0_SECUREP32	=	0x3;
*pREG_SPU0_SECUREP33	=	0x3;
*pREG_SPU0_SECUREP34	=	0x3;
*pREG_SPU0_SECUREP35	=	0x3;
*pREG_SPU0_SECUREP36	=	0x3;
*pREG_SPU0_SECUREP37	=	0x3;
*pREG_SPU0_SECUREP38	=	0x3;
*pREG_SPU0_SECUREP39	=	0x3;
*pREG_SPU0_SECUREP40	=	0x3;
*pREG_SPU0_SECUREP41	=	0x3;
*pREG_SPU0_SECUREP42	=	0x3;
*pREG_SPU0_SECUREP43	=	0x3;
*pREG_SPU0_SECUREP44	=	0x3;
*pREG_SPU0_SECUREP45	=	0x3;
*pREG_SPU0_SECUREP46	=	0x3;
*pREG_SPU0_SECUREP47	=	0x3;
*pREG_SPU0_SECUREP48	=	0x3;
*pREG_SPU0_SECUREP49	=	0x3;
*pREG_SPU0_SECUREP50	=	0x3;
*pREG_SPU0_SECUREP51	=	0x3;
*pREG_SPU0_SECUREP52	=	0x3;
*pREG_SPU0_SECUREP53	=	0x3;
*pREG_SPU0_SECUREP54	=	0x3;
*pREG_SPU0_SECUREP55	=	0x3;
*pREG_SPU0_SECUREP56	=	0x3;
*pREG_SPU0_SECUREP57	=	0x3;
*pREG_SPU0_SECUREP58	=	0x3;
*pREG_SPU0_SECUREP59	=	0x3;
*pREG_SPU0_SECUREP60	=	0x3;
*pREG_SPU0_SECUREP61	=	0x3;
*pREG_SPU0_SECUREP62	=	0x3;
*pREG_SPU0_SECUREP63	=	0x3;
*pREG_SPU0_SECUREP64	=	0x3;
*pREG_SPU0_SECUREP65	=	0x3;
*pREG_SPU0_SECUREP66	=	0x3;
*pREG_SPU0_SECUREP67	=	0x3;
*pREG_SPU0_SECUREP68	=	0x3;
*pREG_SPU0_SECUREP69	=	0x3;
*pREG_SPU0_SECUREP70	=	0x3;
*pREG_SPU0_SECUREP71	=	0x3;
*pREG_SPU0_SECUREP72	=	0x3;
*pREG_SPU0_SECUREP73	=	0x3;
*pREG_SPU0_SECUREP74	=	0x3;
*pREG_SPU0_SECUREP75	=	0x3;
*pREG_SPU0_SECUREP76	=	0x3;
*pREG_SPU0_SECUREP77	=	0x3;
*pREG_SPU0_SECUREP78	=	0x3;
*pREG_SPU0_SECUREP79	=	0x3;
*pREG_SPU0_SECUREP80	=	0x3;
*pREG_SPU0_SECUREP81	=	0x3;
*pREG_SPU0_SECUREP82	=	0x3;
*pREG_SPU0_SECUREP83	=	0x3;
*pREG_SPU0_SECUREP84	=	0x3;
*pREG_SPU0_SECUREP85	=	0x3;
*pREG_SPU0_SECUREP86	=	0x3;
*pREG_SPU0_SECUREP87	=	0x3;
*pREG_SPU0_SECUREP88	=	0x3;
*pREG_SPU0_SECUREP89	=	0x3;
*pREG_SPU0_SECUREP90	=	0x3;
*pREG_SPU0_SECUREP91	=	0x3;
*pREG_SPU0_SECUREP92	=	0x3;
*pREG_SPU0_SECUREP93	=	0x3;
*pREG_SPU0_SECUREP94	=	0x3;
*pREG_SPU0_SECUREP95	=	0x3;
*pREG_SPU0_SECUREP96	=	0x3;
*pREG_SPU0_SECUREP97	=	0x3;
*pREG_SPU0_SECUREP98	=	0x3;
*pREG_SPU0_SECUREP99	=	0x3;
*pREG_SPU0_SECUREP100	=	0x3;
*pREG_SPU0_SECUREP101	=	0x3;
*pREG_SPU0_SECUREP102	=	0x3;
*pREG_SPU0_SECUREP103	=	0x3;
*pREG_SPU0_SECUREP104	=	0x3;
*pREG_SPU0_SECUREP105	=	0x3;
*pREG_SPU0_SECUREP106	=	0x3;
*pREG_SPU0_SECUREP107	=	0x3;
*pREG_SPU0_SECUREP108	=	0x3;
*pREG_SPU0_SECUREP109	=	0x3;
*pREG_SPU0_SECUREP110	=	0x3;
*pREG_SPU0_SECUREP111	=	0x3;
*pREG_SPU0_SECUREP112	=	0x3;
*pREG_SPU0_SECUREP113	=	0x3;
*pREG_SPU0_SECUREP114	=	0x3;
*pREG_SPU0_SECUREP115	=	0x3;
*pREG_SPU0_SECUREP116	=	0x3;
*pREG_SPU0_SECUREP117	=	0x3;
*pREG_SPU0_SECUREP118	=	0x3;
*pREG_SPU0_SECUREP119	=	0x3;
*pREG_SPU0_SECUREP120	=	0x3;
*pREG_SPU0_SECUREP121	=	0x3;
*pREG_SPU0_SECUREP122	=	0x3;
*pREG_SPU0_SECUREP123	=	0x3;
*pREG_SPU0_SECUREP124	=	0x3;
*pREG_SPU0_SECUREP125	=	0x3;
*pREG_SPU0_SECUREP126	=	0x3;
*pREG_SPU0_SECUREP127	=	0x3;
*pREG_SPU0_SECUREP128	=	0x3;
*pREG_SPU0_SECUREP129	=	0x3;
*pREG_SPU0_SECUREP130	=	0x3;
*pREG_SPU0_SECUREP131	=	0x3;
*pREG_SPU0_SECUREP132	=	0x3;
*pREG_SPU0_SECUREP133	=	0x3;
*pREG_SPU0_SECUREP134	=	0x3;
*pREG_SPU0_SECUREP135	=	0x3;
*pREG_SPU0_SECUREP136	=	0x3;
*pREG_SPU0_SECUREP137	=	0x3;
*pREG_SPU0_SECUREP138	=	0x3;
*pREG_SPU0_SECUREP139	=	0x3;
*pREG_SPU0_SECUREP140	=	0x3;
*pREG_SPU0_SECUREP141	=	0x3;
*pREG_SPU0_SECUREP142	=	0x3;
*pREG_SPU0_SECUREP143	=	0x3;
*pREG_SPU0_SECUREP144	=	0x3;
*pREG_SPU0_SECUREP145	=	0x3;
*pREG_SPU0_SECUREP146	=	0x3;
*pREG_SPU0_SECUREP147	=	0x3;
*pREG_SPU0_SECUREP148	=	0x3;
*pREG_SPU0_SECUREP149	=	0x3;
*pREG_SPU0_SECUREP150	=	0x3;
*pREG_SPU0_SECUREP151	=	0x3;
*pREG_SPU0_SECUREP152	=	0x3;
*pREG_SPU0_SECUREP153	=	0x3;
*pREG_SPU0_SECUREP154	=	0x3;
*pREG_SPU0_SECUREP155	=	0x3;
*pREG_SPU0_SECUREP156	=	0x3;
*pREG_SPU0_SECUREP157	=	0x3;
*pREG_SPU0_SECUREP158	=	0x3;
*pREG_SPU0_SECUREP159	=	0x3;
*pREG_SPU0_SECUREP160	=	0x3;
*pREG_SPU0_SECUREP161	=	0x3;
*pREG_SPU0_SECUREP162	=	0x3;
*pREG_SPU0_SECUREP163	=	0x3;
*pREG_SPU0_SECUREP164	=	0x3;
*pREG_SPU0_SECUREP165	=	0x3;
*pREG_SPU0_SECUREP166	=	0x3;
*pREG_SPU0_SECUREP167	=	0x3;
*pREG_SPU0_SECUREP168	=	0x3;
*pREG_SPU0_SECUREP169	=	0x3;
*pREG_SPU0_SECUREP170	=	0x3;
*pREG_SPU0_SECUREP171	=	0x3;
*pREG_SPU0_SECUREP172	=	0x3;
*pREG_SPU0_SECUREP173	=	0x3;
*pREG_SPU0_SECUREP174	=	0x3;
*pREG_SPU0_SECUREP175	=	0x3;
*pREG_SPU0_SECUREP176	=	0x3;
*pREG_SPU0_SECUREP177	=	0x3;
*pREG_SPU0_SECUREP178	=	0x3;
*pREG_SPU0_SECUREP179	=	0x3;
*pREG_SPU0_SECUREP180	=	0x3;
*pREG_SPU0_SECUREP181	=	0x3;
*pREG_SPU0_SECUREP182	=	0x3;
*pREG_SPU0_SECUREP183	=	0x3;
*pREG_SPU0_SECUREP184	=	0x3;
*pREG_SPU0_SECUREP185	=	0x3;
*pREG_SPU0_SECUREP186	=	0x3;
*pREG_SPU0_SECUREP187	=	0x3;
*pREG_SPU0_SECUREP188	=	0x3;
*pREG_SPU0_SECUREP189	=	0x3;
*pREG_SPU0_SECUREP190	=	0x3;
*pREG_SPU0_SECUREP191	=	0x3;
*pREG_SPU0_SECUREP192	=	0x3;
*pREG_SPU0_SECUREP193	=	0x3;
*pREG_SPU0_SECUREP194	=	0x3;
*pREG_SPU0_SECUREP195	=	0x3;
*pREG_SPU0_SECUREP196	=	0x3;
*pREG_SPU0_SECUREP197	=	0x3;
*pREG_SPU0_SECUREP198	=	0x3;
*pREG_SPU0_SECUREP199	=	0x3;
*pREG_SPU0_SECUREP200	=	0x3;
*pREG_SPU0_SECUREP201	=	0x3;
*pREG_SPU0_SECUREP202	=	0x3;
*pREG_SPU0_SECUREP203	=	0x3;
*pREG_SPU0_SECUREP204	=	0x3;
*pREG_SPU0_SECUREP205	=	0x3;
*pREG_SPU0_SECUREP206	=	0x3;
*pREG_SPU0_SECUREP207	=	0x3;
*pREG_SPU0_SECUREP208	=	0x3;
*pREG_SPU0_SECUREP209	=	0x3;
*pREG_SPU0_SECUREP210	=	0x3;
*pREG_SPU0_SECUREP211	=	0x3;
*pREG_SPU0_SECUREP212	=	0x3;
}
//*pREG_SPU0_SECUREP213	=	0x3;
//*pREG_SPU0_SECUREP214	=	0x3;
//*pREG_SPU0_SECUREP215	=	0x3;
//*pREG_SPU0_SECUREP216	=	0x3;
//*pREG_SPU0_SECUREP217	=	0x3;
//*pREG_SPU0_SECUREP218	=	0x3;
//*pREG_SPU0_SECUREP219	=	0x3;
//*pREG_SPU0_SECUREP220	=	0x3;
//*pREG_SPU0_SECUREP221	=	0x3;
//*pREG_SPU0_SECUREP222	=	0x3;
//*pREG_SPU0_SECUREP223	=	0x3;
//*pREG_SPU0_SECUREP224	=	0x3;
//*pREG_SPU0_SECUREP225	=	0x3;
//*pREG_SPU0_SECUREP226	=	0x3;
//*pREG_SPU0_SECUREP227	=	0x3;
//*pREG_SPU0_SECUREP228	=	0x3;
//*pREG_SPU0_SECUREP229	=	0x3;
//*pREG_SPU0_SECUREP230	=	0x3;
//*pREG_SPU0_SECUREP231	=	0x3;
//}


