示例#1
0
文件: spi.cpp 项目: sunpho84/nissa
  //initialize the spi communications
  void init_spi()
  {
    //check not to have initialized
    if(!spi_inited)
      {
	verbosity_lv1_master_printf("Starting spi\n");
	
	//check that we do not have more than one process per node
	if(Kernel_ProcessCount()!=1) crash("only one process per node implemented");
	
	//mark as initialized
	spi_inited=true;
	
	//get coordinates, size and rank in the 5D grid
	set_spi_geometry();
	
	//check that all ranks are first neighbours in SPI grid
	check_all_lattice_neighbours_are_spi_first_neighbours();
	
	//allocate bats
	spi_bat_id[0]=0;
	spi_bat_id[1]=1;
	if(Kernel_AllocateBaseAddressTable(0,&spi_bat_gr,2,spi_bat_id,0)) crash("allocating bat");
	
	////////////////////////////////// init the fifos ///////////////////////////////////
	
	//alloc space for the injection fifos
	uint32_t fifo_size=64*NSPI_FIFO;
	for(int ififo=0;ififo<NSPI_FIFO;ififo++) spi_fifo[ififo]=(uint64_t*)memalign(64,fifo_size);
	
	//set default attributes for inj fifo
	Kernel_InjFifoAttributes_t fifo_attrs[NSPI_FIFO];
	memset(fifo_attrs,0,NSPI_FIFO*sizeof(Kernel_InjFifoAttributes_t));
	
	//initialize them with default attributes
	uint32_t fifo_id[NSPI_FIFO];
	for(int ififo=0;ififo<NSPI_FIFO;ififo++) fifo_id[ififo]=ififo;
	if(Kernel_AllocateInjFifos(0,&spi_fifo_sg_ptr,NSPI_FIFO,fifo_id,fifo_attrs)) crash("allocating inj fifos");
	
	//init the MU MMIO for the fifos
	for(int ififo=0;ififo<NSPI_FIFO;ififo++)
	  {
	    //create the memory region
	    Kernel_MemoryRegion_t mem_region;
	    if(Kernel_CreateMemoryRegion(&mem_region,spi_fifo[NSPI_FIFO-1-ififo],fifo_size))
	      crash("creating memory region %d of bytes",ififo,fifo_size);
	    
	    //initialize the fifos
	    if(Kernel_InjFifoInit(&spi_fifo_sg_ptr,fifo_id[ififo],&mem_region,
				  (uint64_t)spi_fifo[NSPI_FIFO-1-ififo]-(uint64_t)mem_region.BaseVa,fifo_size-1))
	      crash("initializing fifo");
	  }
	
	//activate the fifos
	if(Kernel_InjFifoActivate(&spi_fifo_sg_ptr,NSPI_FIFO,fifo_id,KERNEL_INJ_FIFO_ACTIVATE)) crash("activating fifo");
	
	//check alignment
	CRASH_IF_NOT_ALIGNED(recv_buf,64);
	CRASH_IF_NOT_ALIGNED(send_buf,64);
	
	//get physical address of receiving buffer
	Kernel_MemoryRegion_t mem_region;
	if(Kernel_CreateMemoryRegion(&mem_region,recv_buf,recv_buf_size))
	  crash("creating recv_buf memory region of %d bytes",recv_buf_size);
	
	//set the physical address
	if(MUSPI_SetBaseAddress(&spi_bat_gr,spi_bat_id[0],(uint64_t)recv_buf-
				(uint64_t)mem_region.BaseVa+(uint64_t)mem_region.BasePa))
	  crash("setting base address");
	
	//set receive counter bat to MU style atomic PA addr of the receive counter
	if((uint64_t)(&spi_recv_counter)&0x7) crash("recv counter not 8 byte aligned");
	if(Kernel_CreateMemoryRegion(&mem_region,(void*)&spi_recv_counter,sizeof(uint64_t)))
	  crash("creating memory region of %d bytes",sizeof(uint64_t));
	if(MUSPI_SetBaseAddress(&spi_bat_gr,spi_bat_id[1],MUSPI_GetAtomicAddress((uint64_t)&spi_recv_counter-(uint64_t)mem_region.BaseVa+(uint64_t)mem_region.BasePa,MUHWI_ATOMIC_OPCODE_STORE_ADD))) crash("setting base addr");
	
	//reset number of byte to be received
	spi_recv_counter=0;
	
	//get the send buffer physical address
	if(Kernel_CreateMemoryRegion(&mem_region,send_buf,send_buf_size))
	  crash("creating memory region of %d bytes",send_buf_size);
	spi_send_buf_phys_addr=(uint64_t)send_buf-(uint64_t)mem_region.BaseVa+(uint64_t)mem_region.BasePa;
	
	//find hints for descriptors
	set_spi_hints();
	
#ifdef SPI_BARRIER
	//init the barrier
	if(MUSPI_GIBarrierInit(&spi_barrier,0)) crash("initializing the barrier");
#endif
	verbosity_lv2_master_printf("spi initialized\n");
      }
  }
示例#2
0
int fw_sync_timebase( void ) 
{

    uint64_t numloops = 10;
    uint64_t value;
    uint64_t rc;
    Personality_t *pers = &FW_Personality;    
    uint64_t numthreads;
    uint64_t msr;
    uint64_t geamap8 = 0;
    
    if(!PERS_ENABLED(PERS_ENABLE_MU))
        return 0;    

    if(!PERS_ENABLED(PERS_ENABLE_ND))
        return 0;    
    
    msr = mfmsr();
    mtmsr(msr & ~(MSR_EE | MSR_CE | MSR_ME));
    isync();
    
    numthreads = popcnt64(DCRReadPriv(TESTINT_DCR(THREAD_ACTIVE0))) + popcnt64(DCRReadPriv(TESTINT_DCR(THREAD_ACTIVE1)));
    if(PhysicalThreadID() == 0)
    {
#define WU_MMIO_PRIV_BASE ((volatile unsigned long *)0x3ffe8001c00)
#define SET_THREAD(i)           ((0x300 + (i)*0x40) / sizeof (unsigned long))
        WU_MMIO_PRIV_BASE[SET_THREAD(0)] = WU_DCR__THREAD0_WU_EVENT_SET__GEA_WU_EN_set(0x8);
        
        if(ProcessorID() == 0)
        {
            // Setup classroute 14.  Identical to classroute 15.
            value = DCRReadPriv(ND_500_DCR(CTRL_GI_CLASS_14_15));
            ND_500_DCR__CTRL_GI_CLASS_14_15__CLASS14_UP_PORT_I_insert(value, ND_500_DCR__CTRL_GI_CLASS_14_15__CLASS15_UP_PORT_I_get(value));
            ND_500_DCR__CTRL_GI_CLASS_14_15__CLASS14_UP_PORT_O_insert(value, ND_500_DCR__CTRL_GI_CLASS_14_15__CLASS15_UP_PORT_O_get(value));
            DCRWritePriv(ND_500_DCR(CTRL_GI_CLASS_14_15), value);
            ppc_msync();
            
            // Initialize GI pulse
            MUSPI_GIInit (&GI, 14, 0);
            
            // Initialize the GI barrier interrupt on classroute 14
            DCRWritePriv(MU_DCR(BARRIER_INT_EN), MU_DCR__BARRIER_INT_EN__CLASS14_set(4));
            
            // Route MU MAP4 interrupt to GEA lane 12 (wakeup unit bit 0)
            geamap8 = DCRReadPriv(GEA_DCR(GEA_INTERRUPT_MAP8));
            DCRWritePriv(GEA_DCR(GEA_INTERRUPT_MAP8), GEA_DCR__GEA_INTERRUPT_MAP8__MU_MAP4_set(12));
            rc = MUSPI_GIBarrierInit(&GIBarrier, 15);
        }
        
        // do local barrier
        BeDRAM_ReadIncSat(BeDRAM_LOCKNUM_TIMESYNC_BARRIER);
        while(BeDRAM_Read(BeDRAM_LOCKNUM_TIMESYNC_BARRIER) != numthreads)
        {
        }
        
        if(ProcessorID() == 0)
        {
            // Perform a barrier across all nodes.
            MUSPI_GIBarrierEnterAndWait(&GIBarrier);
            if ( rc != 0 )
            {
                FW_Warning("MUSPI_GIBarrierInit for class route 15 returned rc = %ld.", rc);
                return -1;
            }
            
            // Start gsync counter (for debug)
            DCRWritePriv(TESTINT_DCR(GSYNC_CTR), -1);
        }
        doTimeSync(numloops);
        mtspr(SPRN_TENS, 0xf);
    }
    else if((ProcessorID() == 1) && (pers->Network_Config.PrimordialClassRoute.GlobIntUpPortOutputs == 0))
    {
        BeDRAM_ReadIncSat(BeDRAM_LOCKNUM_TIMESYNC_BARRIER);
        createSendGIPulseThread(numloops);
    }
    else
    {
        BeDRAM_ReadIncSat(BeDRAM_LOCKNUM_TIMESYNC_BARRIER);
        mtspr(SPRN_TENC, 1 << ProcessorThreadID());
        isync();
    }
    
    // Wait for all hwthreads on node
    BeDRAM_ReadIncSat(BeDRAM_LOCKNUM_TIMESYNC_BARRIER);
    while(BeDRAM_Read(BeDRAM_LOCKNUM_TIMESYNC_BARRIER) != numthreads * 2)
    {
    }
    
    if(ProcessorID() == 0)
    {
        value = DCRReadPriv(ND_500_DCR(CTRL_GI_CLASS_14_15));
        ND_500_DCR__CTRL_GI_CLASS_14_15__CLASS14_UP_PORT_I_insert(value, 0);
        ND_500_DCR__CTRL_GI_CLASS_14_15__CLASS14_UP_PORT_O_insert(value, 0);
        DCRWritePriv(ND_500_DCR(CTRL_GI_CLASS_14_15), value);
        ppc_msync();
        
        // Initialize the barrier structure.  
        DCRWritePriv(MU_DCR(BARRIER_INT_EN), MU_DCR__BARRIER_INT_EN__CLASS14_set(0));
        DCRWritePriv(GEA_DCR(GEA_INTERRUPT_MAP8), geamap8);
    }
    WU_MMIO_PRIV_BASE[SET_THREAD(0)] = WU_DCR__THREAD0_WU_EVENT_SET__GEA_WU_EN_set(0);
    
    BeDRAM_ReadIncSat(BeDRAM_LOCKNUM_TIMESYNC_BARRIER);
    while(BeDRAM_Read(BeDRAM_LOCKNUM_TIMESYNC_BARRIER) != numthreads * 3)
    {
    }
    
    mtmsr(msr);
    isync();
    
    return 0;
}