//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"); } }
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; }