#include <stdio.h>
#include <c6x.h>
#include "types.h"
#include "interrupt.h"
#define MAILBOX_BASE_ADDR		0x80c8000
#define RD_MEM_32(addr) 	  	 *(volatile unsigned int*)(addr)
#define WR_MEM_32(addr, data)    do {*(volatile unsigned int*)(addr) =(unsigned int)(data);}while(0)

/*
 *mailbox 9 used for M3
 *mailbox 10 for dsp
 *mailbox 11 for arm
 * */
#define MAILBOX_MESSAGE_M3   (MAILBOX_BASE_ADDR+0x40+0x4*9)
#define MAILBOX_FIFOSTATUS_M3    (MAILBOX_BASE_ADDR+0x80+0x4*9)
#define MAILBOX_MSGSTATUS_M3   (MAILBOX_BASE_ADDR+0xc0+0x4*9)
#define MAILBOX_IRQSTATUS_RAW_U_M3   (MAILBOX_BASE_ADDR+0x100+0x10*2)
#define MAILBOX_IRQSTATUS_CLR_U_M3   (MAILBOX_BASE_ADDR+0x104+0x10*2)
#define MAILBOX_IRQENABLE_SET_U_M3   (MAILBOX_BASE_ADDR+0x108+0x10*2)
#define MAILBOX_IRQENABLE_CLR_U_M3   (MAILBOX_BASE_ADDR+0x10c+0x10*2)

#define MAILBOX_MESSAGE_A8   (MAILBOX_BASE_ADDR+0x40+0x4*11)
#define MAILBOX_FIFOSTATUS_A8    (MAILBOX_BASE_ADDR+0x80+0x4*11)
#define MAILBOX_MSGSTATUS_A8   (MAILBOX_BASE_ADDR+0xc0+0x4*11)
#define MAILBOX_IRQSTATUS_RAW_U_A8   (MAILBOX_BASE_ADDR+0x100+0x10*0)
#define MAILBOX_IRQSTATUS_CLR_U_A8   (MAILBOX_BASE_ADDR+0x104+0x10*0)
#define MAILBOX_IRQENABLE_SET_U_A8   (MAILBOX_BASE_ADDR+0x108+0x10*0)
#define MAILBOX_IRQENABLE_CLR_U_A8   (MAILBOX_BASE_ADDR+0x10c+0x10*0)

#define MAILBOX_MESSAGE_DSP   (MAILBOX_BASE_ADDR+0x40+0x4*10)
#define MAILBOX_FIFOSTATUS_DSP    (MAILBOX_BASE_ADDR+0x80+0x4*10)
#define MAILBOX_MSGSTATUS_DSP   (MAILBOX_BASE_ADDR+0xc0+0x4*10)
#define MAILBOX_IRQSTATUS_RAW_U_DSP   (MAILBOX_BASE_ADDR+0x100+0x10*1)
#define MAILBOX_IRQSTATUS_CLR_U_DSP   (MAILBOX_BASE_ADDR+0x104+0x10*1)
#define MAILBOX_IRQENABLE_SET_U_DSP   (MAILBOX_BASE_ADDR+0x108+0x10*1)
#define MAILBOX_IRQENABLE_CLR_U_DSP   (MAILBOX_BASE_ADDR+0x10c+0x10*1)
/*
 * mailbox 10 arm->dsp
 * mailbox 11 dsp->arm
 * */
/*
 * we use mailbox10 for the test
 * */
void sendmsg_a8(int msg)
{
	WR_MEM_32(MAILBOX_IRQENABLE_SET_U_A8,RD_MEM_32(MAILBOX_IRQENABLE_SET_U_A8) | (0x1<<22));
	WR_MEM_32(MAILBOX_MESSAGE_A8,msg);
}
void sendmsg_m3(int msg)
{
	WR_MEM_32(MAILBOX_IRQENABLE_SET_U_M3,RD_MEM_32(MAILBOX_IRQENABLE_SET_U_M3) | (0x1<<18));
	WR_MEM_32(MAILBOX_MESSAGE_M3,msg);
}
#if 0
int check_memory(int add)
{
	int i;
	unsigned int* tmp;
	tmp = (unsigned int*)add;
	for(i=0;i<1024;i++)
	{
		if(*tmp != i) return 0;
		tmp++;
	}
	return 1;
}
#endif
/*mailbox10*/
int i = 0;
static void MailBoxIsr(void)
{
    unsigned int temp;
    IntDisable(C674X_MASK_INT5);
    IntEventClear(SYS_INT_MAILBOX);
    if(RD_MEM_32(MAILBOX_IRQSTATUS_CLR_U_DSP)&(0x1<<20))
    {
    	while(RD_MEM_32(MAILBOX_MSGSTATUS_DSP))
    	{
    		temp = RD_MEM_32(MAILBOX_MESSAGE_DSP);
    	}
    	WR_MEM_32(MAILBOX_IRQSTATUS_CLR_U_DSP,(0x1<<20));
    }
    IntEnable(C674X_MASK_INT5);
  //  if(check_memory(temp))
    sendmsg_a8(temp);
}
static void MailboxSetUp(void)
{
	WR_MEM_32(MAILBOX_IRQENABLE_CLR_U_DSP,RD_MEM_32(MAILBOX_IRQENABLE_CLR_U_DSP) | (0x1<<20));
	WR_MEM_32(MAILBOX_IRQENABLE_SET_U_DSP,RD_MEM_32(MAILBOX_IRQENABLE_SET_U_DSP) | (0x1<<20));
}
void main (void)
{

	  /* Initialize the DSP interrupt controller */
	    IntDSPINTCInit();

	    /* Register ISR to vector table */
	    IntRegister(C674X_MASK_INT5, MailBoxIsr);

	    /* Map system interrupt to DSP maskable interrupt */
	    IntEventMap(C674X_MASK_INT5, SYS_INT_MAILBOX);

	    /* Enable DSP maskable interrupt */
	    IntEnable(C674X_MASK_INT5);

	    /* Enable DSP interrupts */
	    IntGlobalEnable();
		MailboxSetUp();
	while(1);
}


