Exemplo n.º 1
0
  //install spi descriptors, needed for communticaions
  void spi_descriptor_setup(comm_t &in)
  {
    posix_memalign((void**)&in.descriptors,64,8*sizeof(MUHWI_Descriptor_t));
    CRASH_IF_NOT_ALIGNED(in.descriptors,64);
    
    //create one descriptor per direction
    for(int idir=0;idir<8;idir++)
      if(paral_dir[idir%4])
	{
	  //reset the info
	  MUSPI_Pt2PtDirectPutDescriptorInfo_t dinfo;
	  memset(&dinfo,0,sizeof(MUSPI_Pt2PtDirectPutDescriptorInfo_t));
	  
	  //set the parameters
	  dinfo.Base.Payload_Address=spi_send_buf_phys_addr+in.send_offset[idir];
	  dinfo.Base.Message_Length=in.message_length[idir];
	  dinfo.Base.Torus_FIFO_Map=spi_fifo_map[idir];
	  dinfo.Base.Dest=in.spi_dest[idir];
#ifdef HINTS_DEBUG
	  printf("rank %d setting ABCD hint for dir %d to %u\n",rank,idir,spi_hint_ABCD[idir]);
#endif
	  dinfo.Pt2Pt.Hints_ABCD=0; //this is not working...
	  
	  dinfo.Pt2Pt.Misc1=MUHWI_PACKET_USE_DETERMINISTIC_ROUTING|MUHWI_PACKET_DO_NOT_ROUTE_TO_IO_NODE;
	  //|spi_hint_E[idir]; and this as well
#ifdef HINTS_DEBUG
	  printf("rank %d setting E hint for dir %d to %u\n",rank,idir,spi_hint_E[idir]);
#endif
	  dinfo.Pt2Pt.Misc2=MUHWI_PACKET_VIRTUAL_CHANNEL_DETERMINISTIC;
	  dinfo.Pt2Pt.Skip=8; //for checksumming, skip the header
	  dinfo.DirectPut.Rec_Payload_Base_Address_Id=spi_bat_id[0];
	  dinfo.DirectPut.Rec_Payload_Offset=in.recv_offset[idir];
	  dinfo.DirectPut.Rec_Counter_Base_Address_Id=spi_bat_id[1];
	  dinfo.DirectPut.Rec_Counter_Offset=0;
	  dinfo.DirectPut.Pacing=MUHWI_PACKET_DIRECT_PUT_IS_NOT_PACED;
	  
	  //create the descriptor
	  if(MUSPI_CreatePt2PtDirectPutDescriptor(&in.descriptors[idir],&dinfo)) crash("creating the descriptor");
	}
  }
Exemplo n.º 2
0
static void init()
{
  int rc = 0;
  uint32_t fifoid=0;
  uint32_t subgroup, group;
  int i;

  /* If we are the 1st process, set up the rget inj fifo */
  if ( Kernel_ProcessorID() == 0 )
    {
      /* Set up an rget injection fifo to be used by all processes on this node.
       * It is at a well-known location...subgroup 0, fifo 0.
       * - Allocate storage for an injection fifo
       * - Allocate and initialize that injection fifo.
       * - Activate that injection fifo.
       */
      rc = posix_memalign( (void**)&_ififoPtr, 64, _injFifoSize );
      assert ( rc == 0 );

      /* Set user fifo attribute. */
      Kernel_InjFifoAttributes_t injFifoAttrs[1];
      injFifoAttrs[0].RemoteGet = 1;
      injFifoAttrs[0].System    = 0;
      injFifoAttrs[0].Priority  = 0;
      
      subgroup = 0;

      rc = Kernel_AllocateInjFifos (subgroup,
				    &_ififo_subgroup,
				    1,
				    &fifoid,
				    injFifoAttrs);
      assert ( rc == 0 );
      
      Kernel_MemoryRegion_t  mregion;
      Kernel_CreateMemoryRegion ( &mregion,
				  _ififoPtr,
				  _injFifoSize );
      
      rc = Kernel_InjFifoInit( &_ififo_subgroup,
			       fifoid,
			       &mregion,
			       (uint64_t)_ififoPtr -
			       (uint64_t)mregion.BaseVa,
			       _injFifoSize-1 );
      assert ( rc == 0 );
      
      rc = Kernel_InjFifoActivate ( &_ififo_subgroup,
				    1,
				    &fifoid,
				    KERNEL_INJ_FIFO_ACTIVATE );
      assert ( rc == 0 );

      /* Allocate a Base Address Table Entry for all processes on the node to use,
       * and set its value to zero. 
       */
      uint32_t batId = 0;
      rc = Kernel_AllocateBaseAddressTable( 0, /* subgroup */
					    &_batSubgroup,
					    1,
					    &batId,
					    0 /* "User" access */);
      assert ( rc == 0 );
      
      MUHWI_BaseAddress_t baseAddress;
      baseAddress = 0;
      
      rc = MUSPI_SetBaseAddress ( &_batSubgroup,
				  batId,
				  baseAddress );
      assert ( rc == 0 );
    }  

  /* Set up a reception fifo to receive packets.
   * - Allocate storage for a reception fifo
   * - Use the subgroup equal to our HW thread ID.
   * - Allocate and initialize that reception fifo.
   * - Enable that reception fifo.
   */
  rc = posix_memalign( (void**)&_rfifoPtr, 32, _recFifoSize );
  assert ( rc == 0 );

  Kernel_RecFifoAttributes_t recFifoAttrs[1];
  recFifoAttrs[0].System = 0;

  subgroup = Kernel_ProcessorID();
  group    = Kernel_ProcessorCoreID();

  rc = Kernel_AllocateRecFifos (subgroup,
				&_rfifo_subgroup,
				1,
				&fifoid,
				recFifoAttrs);
  assert ( rc == 0 );

  _rfifoShadowPtr = &_rfifo_subgroup._recfifos[fifoid];

  uint64_t recFifoEnableBits;

  Kernel_MemoryRegion_t  mregion;
  Kernel_CreateMemoryRegion ( &mregion,
			      _rfifoPtr,
			      _recFifoSize );
	      
  rc = Kernel_RecFifoInit( &_rfifo_subgroup, 
			   fifoid,
			   &mregion, 
			   (uint64_t)_rfifoPtr -
			   (uint64_t)mregion.BaseVa,
			   _recFifoSize-1 );
  assert ( rc == 0 );

  recFifoEnableBits = ( 0x0000000000000001ULL << 
			( 15 - 
			  ( ( (Kernel_ProcessorThreadID())*BGQ_MU_NUM_REC_FIFOS_PER_SUBGROUP) + 
			    fifoid ) ) );
		  
  rc = Kernel_RecFifoEnable ( group,
			      recFifoEnableBits );
  assert ( rc == 0 );
  
  _globalRecFifoId = subgroup * BGQ_MU_NUM_REC_FIFOS_PER_SUBGROUP;

  /* Allocate NUM_BUFS send and recv buffers */
  for (i=0; i<NUM_BUFS; i++)
    {
      int size = (1<<i)*1024;

      rc = posix_memalign( (void**)&_sBuff[i], 8, size );
      assert ( rc == 0 );

      /* Init the buffer */
      int j;
      unsigned char value=i;
      unsigned char *bufPtr=_sBuff[i];
      for (j=0; j<size; j++)
	{
	  *bufPtr = value++;
	  bufPtr++;
	}

      Kernel_MemoryRegion_t  mregion;
      Kernel_CreateMemoryRegion ( &mregion,
				  _sBuff[i],
				  size );
	      
      _sBuffPA[i] = 
	(uint64_t)_sBuff[i] -
	(uint64_t)mregion.BaseVa +
	(uint64_t)mregion.BasePa;

      rc = posix_memalign( (void**)&_rBuff[i], 8, size );
      assert ( rc == 0 );

      Kernel_CreateMemoryRegion ( &mregion,
				  _rBuff[i],
				  size );
	      
      _rBuffPA[i] = 
	(uint64_t)_rBuff[i] -
	(uint64_t)mregion.BaseVa +
	(uint64_t)mregion.BasePa;
    }

  /* Obtain our node coordinates */
  Personality_t personality;
  Kernel_GetPersonality(&personality, sizeof(personality));
  myCoords.Destination.A_Destination = personality.Network_Config.Acoord;
  myCoords.Destination.B_Destination = personality.Network_Config.Bcoord;
  myCoords.Destination.C_Destination = personality.Network_Config.Ccoord;
  myCoords.Destination.D_Destination = personality.Network_Config.Dcoord;
  myCoords.Destination.E_Destination = personality.Network_Config.Ecoord;
  
  /* Build the remote get descriptor model */
  {
    MUSPI_Pt2PtRemoteGetDescriptorInfo_t i;
    memset(&i, 0x00, sizeof(i));
    i.Base.Pre_Fetch_Only  = MUHWI_DESCRIPTOR_PRE_FETCH_ONLY_NO;
    i.Base.Payload_Address = 0; /* To be set by the agent */
    i.Base.Message_Length  = sizeof(MUHWI_Descriptor_t);
    i.Base.Torus_FIFO_Map  = MUHWI_DESCRIPTOR_TORUS_FIFO_MAP_PRIORITY;
    i.Base.Dest.Destination.Destination = myCoords.Destination.Destination;
    i.Pt2Pt.Hints_ABCD     = 0;
    i.Pt2Pt.Misc1          = MUHWI_PACKET_USE_DETERMINISTIC_ROUTING;
    i.Pt2Pt.Misc2          = MUHWI_PACKET_VIRTUAL_CHANNEL_HIGH_PRIORITY;
    i.Pt2Pt.Skip           = 0;
    i.RemoteGet.Type             = MUHWI_PACKET_TYPE_GET;
    i.RemoteGet.Rget_Inj_FIFO_Id = 0;
    rc = MUSPI_CreatePt2PtRemoteGetDescriptor( &_rgetDesc,
					       &i
					     );
    assert ( rc == 0 );
  }

  /* Build the data descriptor model */
  {
    MUSPI_Pt2PtDirectPutDescriptorInfo_t i;
    memset(&i, 0x00, sizeof(i));
    i.Base.Pre_Fetch_Only  = MUHWI_DESCRIPTOR_PRE_FETCH_ONLY_NO;
    i.Base.Payload_Address = 0; /* To be set at runtime */
    i.Base.Message_Length  = 0; /* To be set at runtime */
    i.Base.Torus_FIFO_Map  = MUHWI_DESCRIPTOR_TORUS_FIFO_MAP_LOCAL0;
    i.Base.Dest.Destination.Destination = myCoords.Destination.Destination;
    i.Pt2Pt.Hints_ABCD     = 0;
    i.Pt2Pt.Misc1          = MUHWI_PACKET_USE_DETERMINISTIC_ROUTING;
    i.Pt2Pt.Misc2          = MUHWI_PACKET_VIRTUAL_CHANNEL_DETERMINISTIC;
    i.Pt2Pt.Skip           = 0;
    i.DirectPut.Rec_Payload_Base_Address_Id = 0;
    i.DirectPut.Rec_Payload_Offset          = 0; /* To be set at runtime */
    i.DirectPut.Rec_Counter_Base_Address_Id = 0;
    i.DirectPut.Rec_Counter_Offset          = 0; /* Not used...agent uses its own */
    i.DirectPut.Pacing                      = MUHWI_PACKET_DIRECT_PUT_IS_NOT_PACED;
    rc = MUSPI_CreatePt2PtDirectPutDescriptor( &_dataDesc,
					       &i
					     );
    assert ( rc == 0 );
  }

  /* Build the completion descriptor model */
  {
    MUSPI_Pt2PtMemoryFIFODescriptorInfo_t i;  
    memset(&i, 0x00, sizeof(i));
    i.Base.Pre_Fetch_Only  = MUHWI_DESCRIPTOR_PRE_FETCH_ONLY_NO;
    i.Base.Payload_Address = 0;
    i.Base.Message_Length  = 0;
    i.Base.Torus_FIFO_Map  = MUHWI_DESCRIPTOR_TORUS_FIFO_MAP_LOCAL0;
    i.Base.Dest.Destination.Destination = myCoords.Destination.Destination;
    i.Pt2Pt.Hints_ABCD     = 0;
    i.Pt2Pt.Misc1          = MUHWI_PACKET_USE_DETERMINISTIC_ROUTING;
    i.Pt2Pt.Misc2          = MUHWI_PACKET_VIRTUAL_CHANNEL_DETERMINISTIC;
    i.Pt2Pt.Skip           = 0;
    i.MemFIFO.Rec_FIFO_Id  = _globalRecFifoId;
    i.MemFIFO.Rec_Put_Offset = 0; /* Will contain the message number at runtime */
    rc = MUSPI_CreatePt2PtMemoryFIFODescriptor( &_completionDesc,
						&i
					      );
    assert ( rc == 0 );
  }

  /* Initialize request data structures */
  memset(_requestStatus,0x00,sizeof(_requestStatus));

  /* Wait to ensure this fifo has been allocated on process 0 before proceeding. */
  sleep(10);
  
}
Exemplo n.º 3
0
int test_main ( void ) {

    if (PhysicalThreadIndex() > 0)       // run  a single core test.
        test_exit(0);

    int rc=0;
    printf("Torus Remote Get Atomic Test\n");

    // Perform initialization of the network and mu
    Personality_t *pers;

    pers = fwext_getPersonality();
    uint64_t p1 = pers->Kernel_Config.NodeConfig & PERS_ENABLE_Mambo;
    if (p1) is_mambo = 1;

    // ND and MU init is done in firmware, but we disable it in svchost and
    // call it directly here because it performs much better.
    // #if 0
    fw_nd_set_verbose(0);  // if 1, prints all dcr commands, don't use on cycle sim
    // on cycle sim, can have DcrMonitory trace DCR commands

    rc = fw_nd_reset_release(pers);

    if(rc)
    {
        TRACE(("fw_nd_reset_release failed with rc=%d\n",rc));
        test_exit (rc);
    }

    fw_mu_set_verbose(0);  // if 1, prints all dcr commands, don't use on cycle sim
    // on cycle sim, can have DcrMonitory trace DCR commands

    rc = fw_mu_reset_release(pers);

    if(rc)
    {
        printf("fw_mu_reset_release failed with rc=%d\n",rc);
        test_exit (rc);
    }
    // #endif // if 0

    uint64_t max_value = ~0;

    fw_mu_set_sys_range(0, /* range_id */
                        0, /* min_value */
                        max_value);

    fw_mu_set_usr_range(0, /* range_id */
                        0, /* min_value */
                        max_value);

    /*   fw_mu_set_imfifo_rget   (1, 1); */
    /*   fw_mu_set_imfifo_system (1, 0); */

    TRACE(("Network and MU Initialization is complete\n"));

#else
int main(int argc, char **argv)
{
    int rc;
#endif

    uint i = 0;
    // Destination for Remote Get packet
    MUHWI_Destination_t dest;
    MUSPI_SetUpDestination ( &dest, 0, 0, 0, 0, 0 );

    MUSPI_InjFifoSubGroup_t   fifo_subgroup;

    uint64 message_size_in_bytes_remote_get = MESSAGE_SIZE_REMOTE_GET;
    uint64 message_size_in_bytes_direct_put = MESSAGE_SIZE_DIRECT_PUT;

    TRACE(("main(): Injection Memory FIFO (0,0,0), Send Remote Get Message with Atomic Increment\n"));


//#ifdef PRINT_DEBUG_MESSAGES
    printf("Start!\n");
//#endif

    // ------------------------------------------------------
    // allocates area for message_sent_remote_get[] buffer (RemoteGet)
    // ------------------------------------------------------
    uint64 *message_sent_remote_get = (uint64 *)malloc(message_size_in_bytes_remote_get);
    uint64 *message_sent_direct_put = (uint64 *)malloc(message_size_in_bytes_direct_put);

    TRACE(("message_sent_remote_get (address) = %p\n", message_sent_remote_get));
    TRACE(("message_size_in_bytes_remote_get = %lld\n", message_size_in_bytes_remote_get));

    TRACE(("message_sent_direct_put (address) = %p\n", message_sent_direct_put));
    TRACE(("message_size_in_bytes_direct_put = %lld\n", message_size_in_bytes_direct_put));

    // Initializes the message_sent_remote_get[] buffer
    for (i=0; i<message_size_in_bytes_remote_get/8; i++)
        message_sent_remote_get[i] = 0x00ull;  // 8-bytes

    Kernel_MemoryRegion_t  mregionSentRemoteGet;
    rc = Kernel_CreateMemoryRegion ( &mregionSentRemoteGet,
                                     message_sent_remote_get,
                                     message_size_in_bytes_remote_get );

    if ( rc != 0)
    {
        printf("Kernel_CreateMemoryRegion failed for message_sent_remote_get with rc=%d\n",rc);
#ifdef __FWEXT__
        test_exit(1);
#else
        exit(1);
#endif
    }


    // Initializes the message_sent[] buffer
    *message_sent_direct_put = (uint64)ATOMIC_COUNTER_INITIAL_VALUE;  // 8-bytes
    uint64_t expected_counter_value = ATOMIC_COUNTER_INITIAL_VALUE + RECEIVE_BUFFER_INITIAL_VALUE;

    Kernel_MemoryRegion_t  mregionSentDirectPut;
    rc = Kernel_CreateMemoryRegion ( &mregionSentDirectPut,
                                     message_sent_direct_put,
                                     message_size_in_bytes_direct_put );

    if ( rc != 0)
    {
        printf("Kernel_CreateMemoryRegion failed for message_sent_direct_put with rc=%d\n",rc);
#ifdef __FWEXT__
        test_exit(1);
#else
        exit(1);
#endif
    }

    // Get an atomic address for the message_sent buffer.

    uint64_t message_sent_atomic_address = MUSPI_GetAtomicAddress (
            (uint64_t)message_sent_direct_put -
            (uint64_t)mregionSentDirectPut.BaseVa +
            (uint64_t)mregionSentDirectPut.BasePa,
            MUHWI_ATOMIC_OPCODE_LOAD_INCREMENT );

    TRACE(("message_sent_direct_put (atomic address) = 0x%llx\n",
           (long long unsigned int)message_sent_atomic_address));

    /////////////////////////////////////////////////

    typedef struct recvArea
    {
        volatile uint64 counter;
        unsigned char   recvBuffer[MESSAGE_SIZE_DIRECT_PUT];
    } recvArea_t;

    // Allocate space for the reception counter and the receive buffer

    recvArea_t *recvAreaPtr = (recvArea_t*)malloc ( sizeof(recvArea_t) );
    if ( !recvAreaPtr )
    {
        printf("Allocating recvArea failed\n");
#ifdef __FWEXT__
        test_exit(1);
#else
        exit(1);
#endif
    }

    volatile uint64 *counterAddress    = (volatile uint64*)&(recvAreaPtr->counter);
    unsigned char   *recvBufferAddress = (unsigned char  *)&(recvAreaPtr->recvBuffer[0]);

    *((uint64*)recvBufferAddress) = RECEIVE_BUFFER_INITIAL_VALUE;

    // Get a memory region for the recvArea.

    Kernel_MemoryRegion_t  recvAreaMemRegion;
    rc = Kernel_CreateMemoryRegion ( &recvAreaMemRegion,
                                     recvAreaPtr,
                                     sizeof(recvArea_t) );

    if ( rc != 0)
    {
        printf("Kernel_CreateMemoryRegion failed for recvAreaMemRegion with rc=%d\n",rc);
#ifdef __FWEXT__
        test_exit(1);
#else
        exit(1);
#endif
    }

    // Calculate the offsets of the counter and receive buffer from the base address.

    uint64_t recvAreaBasePA   = (uint64_t)recvAreaMemRegion.BasePa;
    uint64_t counterOffset    = (uint64_t)counterAddress - (uint64_t)recvAreaMemRegion.BaseVa;
    uint64_t recvBufferOffset = (uint64_t)recvBufferAddress - (uint64_t)recvAreaMemRegion.BaseVa;

    TRACE(("counterAddress=%p, recvBufferAddress=%p, recvAreaBasePA=0x%llx, counterOffset=0x%llx, recvBufferOffset=0x%llx\n",counterAddress, recvBufferAddress,
           (long long unsigned int)recvAreaBasePA,
           (long long unsigned int)counterOffset,
           (long long unsigned int)recvBufferOffset));

    //////////////////////////////////////////////////////////////
    // Initialize base address table and atomic counter info
    //////////////////////////////////////////////////////////////
    /* Set up the base address table */
    uint32_t batids[1] = {0};
    MUSPI_BaseAddressTableSubGroup_t bat;
    rc = Kernel_AllocateBaseAddressTable ( 0,
                                           &bat,
                                           1,
                                           batids,
                                           0 /* "User" use */ );
    if (rc != 0)
    {
        printf("Kernel_AllocateBaseAddressTable failed with rc=%d\n",rc);
#ifdef __FWEXT__
        test_exit(1);
#else
        exit(1);
#endif
    }

    rc = MUSPI_SetBaseAddress ( &bat,
                                0,
                                (uint64_t)recvAreaMemRegion.BasePa );
    if (rc != 0)
    {
        printf("MUSPI_SetBaseAddress failed with rc=%d\n",rc);
#ifdef __FWEXT__
        test_exit(1);
#else
        exit(1);
#endif
    }

    TRACE(("Set BaseAddressTable entry slot 0 to 0x%llx\n",
           (long long unsigned int)recvAreaMemRegion.BasePa));

    uint64_t muAtomicCounterOffset = MUSPI_GetAtomicOffsetFromBaseAddress (
                                         &bat,
                                         0,
                                         recvAreaBasePA + counterOffset,
                                         MUHWI_ATOMIC_OPCODE_STORE_ADD );

    uint64_t muAtomicRecvBufferOffset = MUSPI_GetAtomicOffsetFromBaseAddress (
                                            &bat,
                                            0,
                                            recvAreaBasePA + recvBufferOffset,
                                            MUHWI_ATOMIC_OPCODE_STORE_ADD );

    TRACE(("main(): recvCounterVa=%p, recvAreaBasePA=0x%llx, muAtomicCounterOffset=0x%llx, muAtomicRecvBufferOffset=0x%llx\n",
           &(recvAreaPtr->counter),
           (long long unsigned int)recvAreaBasePA,
           (long long unsigned int)muAtomicCounterOffset,
           (long long unsigned int)muAtomicRecvBufferOffset));

    //////////////////////////////////////////////////////////////
    // Create a DirectPut Descriptor and copy it into the
    // message payload
    //////////////////////////////////////////////////////////////
    TRACE(("main(): Configures direct put descriptor\n"));

    MUSPI_Pt2PtDirectPutDescriptorInfo_t mu_iDirectPutDescriptorInfo;
    mu_iDirectPutDescriptorInfo.Base.Pre_Fetch_Only  = MUHWI_DESCRIPTOR_PRE_FETCH_ONLY_NO;
    mu_iDirectPutDescriptorInfo.Base.Payload_Address = message_sent_atomic_address;
    mu_iDirectPutDescriptorInfo.Base.Message_Length  = message_size_in_bytes_direct_put;
    mu_iDirectPutDescriptorInfo.Base.Torus_FIFO_Map  = MUHWI_DESCRIPTOR_TORUS_FIFO_MAP_AP;
    mu_iDirectPutDescriptorInfo.Base.Dest            = dest;
    mu_iDirectPutDescriptorInfo.Pt2Pt.Hints_ABCD = MUHWI_PACKET_HINT_AP;
    mu_iDirectPutDescriptorInfo.Pt2Pt.Misc1      = MUHWI_PACKET_HINT_E_NONE |
            MUHWI_PACKET_DO_NOT_ROUTE_TO_IO_NODE |
            MUHWI_PACKET_USE_DETERMINISTIC_ROUTING |
            MUHWI_PACKET_DO_NOT_DEPOSIT;
    mu_iDirectPutDescriptorInfo.Pt2Pt.Misc2      = MUHWI_PACKET_VIRTUAL_CHANNEL_DETERMINISTIC;
    mu_iDirectPutDescriptorInfo.Pt2Pt.Skip       = 0;

    mu_iDirectPutDescriptorInfo.DirectPut.Rec_Payload_Base_Address_Id = 0;
    mu_iDirectPutDescriptorInfo.DirectPut.Rec_Payload_Offset          = muAtomicRecvBufferOffset;
    mu_iDirectPutDescriptorInfo.DirectPut.Rec_Counter_Base_Address_Id = 0;
    mu_iDirectPutDescriptorInfo.DirectPut.Rec_Counter_Offset          = muAtomicCounterOffset;
    mu_iDirectPutDescriptorInfo.DirectPut.Pacing                      = MUHWI_PACKET_DIRECT_PUT_IS_NOT_PACED;

    rc = MUSPI_CreatePt2PtDirectPutDescriptor( &mu_iDirectPutDescriptor,
            &mu_iDirectPutDescriptorInfo
                                             );
    if (rc != 0)
    {
        printf("MUSPI_CreatePt2PtDirectPutDescriptor failed with rc=%d\n",rc);
#ifdef __FWEXT__
        test_exit(1);
#else
        exit(1);
#endif
    }

    //MUSPI_DescriptorDumpHex("Direct Put Descriptor",
    //		    &mu_iDirectPutDescriptor);

    // Copy Descriptor into RemoteGet message payload

    memcpy((char *)((void *)message_sent_remote_get), (char *)((void *)(&mu_iDirectPutDescriptor)), message_size_in_bytes_remote_get);


    /////////////////////////////////////////////////////////////
    // RemoteGet message
    // Create a remote get descriptor
    /////////////////////////////////////////////////////////////
    TRACE(("main(): Configures remote get descriptor\n"));

    MUSPI_Pt2PtRemoteGetDescriptorInfo_t mu_iRemoteGetDescriptorInfo;
    mu_iRemoteGetDescriptorInfo.Base.Pre_Fetch_Only  = MUHWI_DESCRIPTOR_PRE_FETCH_ONLY_NO;
    mu_iRemoteGetDescriptorInfo.Base.Payload_Address = (uint64_t)message_sent_remote_get - (uint64_t)mregionSentRemoteGet.BaseVa + (uint64_t)mregionSentRemoteGet.BasePa;
    mu_iRemoteGetDescriptorInfo.Base.Message_Length  = message_size_in_bytes_remote_get;
    mu_iRemoteGetDescriptorInfo.Base.Torus_FIFO_Map  = MUHWI_DESCRIPTOR_TORUS_FIFO_MAP_AP;
    mu_iRemoteGetDescriptorInfo.Base.Dest            = dest;
    mu_iRemoteGetDescriptorInfo.Pt2Pt.Hints_ABCD = MUHWI_PACKET_HINT_AP;
    mu_iRemoteGetDescriptorInfo.Pt2Pt.Misc1      = MUHWI_PACKET_HINT_E_NONE |
            MUHWI_PACKET_DO_NOT_ROUTE_TO_IO_NODE |
            MUHWI_PACKET_USE_DETERMINISTIC_ROUTING |
            MUHWI_PACKET_DO_NOT_DEPOSIT;
    mu_iRemoteGetDescriptorInfo.Pt2Pt.Misc2      = MUHWI_PACKET_VIRTUAL_CHANNEL_DETERMINISTIC;
    mu_iRemoteGetDescriptorInfo.Pt2Pt.Skip       = 0;
    mu_iRemoteGetDescriptorInfo.RemoteGet.Type             = MUHWI_PACKET_TYPE_GET;
    mu_iRemoteGetDescriptorInfo.RemoteGet.Rget_Inj_FIFO_Id = 1; // Fifo 1 is for remote get use

    // Prepares Injection Memory FIFO Descriptor (RemoteGet)
    rc = MUSPI_CreatePt2PtRemoteGetDescriptor( &mu_iRemoteGetDescriptor,
            &mu_iRemoteGetDescriptorInfo
                                             );
    if (rc != 0)
    {
        printf("MUSPI_CreatePt2PtRemoteGetDescriptor failed with rc=%d\n",rc);
#ifdef __FWEXT__
        test_exit(1);
#else
        exit(1);
#endif
    }

    //    MUSPI_DescriptorDumpHex("Remote Get Descriptor",
    //		    &mu_iRemoteGetDescriptor);

    /////////////////////////////////////////////////////////////////
    // Configures Injection Memory FIFO Registers
    // - fifo 0 that the core injects descriptors into
    // - fifo 1 that the MU injects remote get payload into
    /////////////////////////////////////////////////////////////////
    TRACE(("main(): Configures Injection Memory FIFO Registers\n"));

    void *injMemoryFifoPtr, *memoryForInjMemoryFifoPtr;
    rc = malloc_memalign ( &memoryForInjMemoryFifoPtr,
                           &injMemoryFifoPtr,
                           64,
                           INJ_MEMORY_FIFO_SIZE+1 );
    if (rc)
    {
        printf("inj_memory_fifo malloc failed with rc=%d\n",rc);
#ifdef __FWEXT__
        test_exit(1);
#else
        exit(1);
#endif
    }

    void *rgetMemoryFifoPtr, *memoryForRgetMemoryFifoPtr;
    rc = malloc_memalign ( &memoryForRgetMemoryFifoPtr,
                           &rgetMemoryFifoPtr,
                           64,
                           INJ_MEMORY_FIFO_SIZE+1 );
    if (rc)
    {
        printf("rget_memory_fifo malloc failed with rc=%d\n",rc);
#ifdef __FWEXT__
        test_exit(1);
#else
        exit(1);
#endif
    }

    uint32_t fifoid[2] = { 0, 1 };

    Kernel_InjFifoAttributes_t injFifoAttrs[2];
    injFifoAttrs[0].RemoteGet = 0;
    injFifoAttrs[0].System    = 0;
    injFifoAttrs[1].RemoteGet = 1;
    injFifoAttrs[1].System    = 0;

    rc = Kernel_AllocateInjFifos (0, &fifo_subgroup, 2,
                                  fifoid, injFifoAttrs);
    if ( rc != 0)
    {
        printf("Kernel_AllocateInjFifos failed with rc=%d\n",rc);
#ifdef __FWEXT__
        test_exit(1);
#else
        exit(1);
#endif
    }

    Kernel_MemoryRegion_t  mregionInj;
    rc = Kernel_CreateMemoryRegion ( &mregionInj,
                                     injMemoryFifoPtr,
                                     INJ_MEMORY_FIFO_SIZE + 1 );

    if ( rc != 0)
    {
        printf("Kernel_CreateMemoryRegion failed for injMemoryFifoPtr with rc=%d\n",rc);
#ifdef __FWEXT__
        test_exit(1);
#else
        exit(1);
#endif
    }

    Kernel_MemoryRegion_t  mregionRget;
    rc = Kernel_CreateMemoryRegion ( &mregionRget,
                                     rgetMemoryFifoPtr,
                                     INJ_MEMORY_FIFO_SIZE + 1 );

    if ( rc != 0)
    {
        printf("Kernel_CreateMemoryRegion failed for rgetMemoryFifoPtr with rc=%d\n",rc);
#ifdef __FWEXT__
        test_exit(1);
#else
        exit(1);
#endif
    }

    rc = Kernel_InjFifoInit (&fifo_subgroup, fifoid[0], &mregionInj,
                             (uint64_t)injMemoryFifoPtr -
                             (uint64_t)mregionInj.BaseVa,
                             INJ_MEMORY_FIFO_SIZE);
    if (rc != 0)
    {
        printf("Kernel_InjFifoInit Inj failed with rc=%d, errno=%d\n",rc,errno);
#ifdef __FWEXT__
        test_exit(1);
#else
        exit(1);
#endif
    }

    rc = Kernel_InjFifoInit (&fifo_subgroup, fifoid[1], &mregionRget,
                             (uint64_t)rgetMemoryFifoPtr -
                             (uint64_t)mregionRget.BaseVa,
                             INJ_MEMORY_FIFO_SIZE);
    if (rc != 0)
    {
        printf("Kernel_InjFifoInit Rget failed with rc=%d, errno=%d\n",rc,errno);
#ifdef __FWEXT__
        test_exit(1);
#else
        exit(1);
#endif
    }

    rc = Kernel_InjFifoActivate (&fifo_subgroup, 2, fifoid, KERNEL_INJ_FIFO_ACTIVATE);
    if (rc != 0)
    {
        printf("Kernel_InjFifoActivate Inj failed with rc=%d, errno=%d\n",rc,errno);
#ifdef __FWEXT__
        test_exit(1);
#else
        exit(1);
#endif
    }


    // ---------------------------------------------
    //    Reception Side
    // ---------------------------------------------


    /*     *data_counter_base_address = REC_PAYLOAD_BASE_ADDRESS; */
    /*     printf("data_counter_base_address = %p\n", data_counter_base_address); */

    // Loop, sending the remote get, waiting for the reception counter to hit zero,
    // and verifying the received counter's value.
    // for (i=0; i<num_iterations; i++)  /** disable loop **/
    {

        // Let's initialize the Counter for corresponding Counter Id
        // Note: counter is initialized with the message size
        // updates counter with number of bytes sent
        *counterAddress = MESSAGE_SIZE_DIRECT_PUT;

        // -----------------------------------------------------------
        // Processor Advances Tail pointer - Descriptor is 64-bytes
        // MU should Inject (RemoteGet) message into the Torus
        // -----------------------------------------------------------

        // Let's Inject the (RemoteGet) Descriptor into the Injection Memory FIFO
#if 1
        printf("main(): Inject Descriptor into Injection Memory FIFO\n");
#endif

        rc = MUSPI_InjFifoInject (MUSPI_IdToInjFifo(fifoid[0], &fifo_subgroup),
                                  (void *)(&mu_iRemoteGetDescriptor) );

        if (rc < 0) // Should have injected 1 descriptor
        {
            printf("MUSPI_InjFifoInject failed with rc=%d\n",rc);
#ifdef __FWEXT__
            test_exit(1);
#else
            exit(1);
#endif
        }

#ifndef __FWEXT__
        printf("main(): Successful injection of remote get descriptor\n");
#endif

        // //////////////////////////////////////////////////
        //      Reception side, check counter value
        // //////////////////////////////////////////////////

        uint64 volatile counter_value;

        // wait for the counter to reach ZERO
        while (1) {

            counter_value = *counterAddress;

            if (counter_value == 0)
            {
                //
#if 1
                printf("counter is now ZERO !!!!\n");
#endif

                break;
            }
        }
        _bgq_msync(); // Ensure data is available to all cores.


        // Let's print the Received Message contents

        //put_offset = (uint64)mu_pktHdrDirectPut.Put_Offset_LSB;

#ifndef __FWEXT__
        printf("recvBufferAddress = %p\n", recvBufferAddress);
        printf("---Prints Received Message contents\n");

        Print_Message((unsigned char *)recvBufferAddress, message_size_in_bytes_direct_put);

        printf("---Where Received Message is being stored: recvBufferAddress = %p\n", recvBufferAddress);
        printf("---Checks Received Message contents(size = %lld)\n", message_size_in_bytes_direct_put);
#endif

        uint64_t receivedCounterValue = *((uint64_t*)recvBufferAddress);

        if ( receivedCounterValue == expected_counter_value )
        {
            printf("---Received Counter Value = %llu\n",
                   (long long unsigned int)receivedCounterValue);
        }
        else
        {
            printf("ERROR: Received Counter Value = %llu, expected %llu\n",
                   (long long unsigned int)receivedCounterValue,
                   (long long unsigned int)expected_counter_value);
#ifdef __FWEXT__
            test_exit(1);
#else
            exit(1);
#endif
        }


        if ( *message_sent_direct_put == ATOMIC_COUNTER_INITIAL_VALUE+1 )
        {
            printf("---Sent Counter Value = %llu\n",
                   (long long unsigned int)*message_sent_direct_put);
        }
        else
        {
            printf("ERROR: Sent Counter Value = %llu, expected %llu\n",
                   (long long unsigned int)*message_sent_direct_put,
                   (long long unsigned int)(ATOMIC_COUNTER_INITIAL_VALUE+1));
#ifdef __FWEXT__
            test_exit(1);
#else
            exit(1);
#endif
        }

    }

    //printf("All counter values passed\n");

#ifdef __FWEXT__

    if ( is_mambo == 0 ) // Termination checks don't work in mambo.  ErrInt DCRs are not zero.
    {
        rc = fw_nd_term_check(pers);
        if (rc)
        {
            printf("ERROR: fw_nd_term_check failed with rc=%d\n",rc);
            test_exit(1);
        }

        rc = fw_mu_term_check(pers);
        if (rc)
        {
            printf("ERROR: fw_mu_term_check failed with rc=%d\n",rc);
            test_exit(1);
        }
    }

#endif

    printf("Done!\n");

#ifdef  __FWEXT__
    test_exit (0);
#endif

    return 0;
}
Exemplo n.º 4
0
void create_descriptors(MUHWI_Descriptor_t * descriptors, uint64_t * messageSizes, uint64_t * soffsets,
                        uint64_t * roffsets, const unsigned int num_dirs) {
    uint64_t anyFifoMap =
        MUHWI_DESCRIPTOR_TORUS_FIFO_MAP_AM |
        MUHWI_DESCRIPTOR_TORUS_FIFO_MAP_AP |
        MUHWI_DESCRIPTOR_TORUS_FIFO_MAP_BM |
        MUHWI_DESCRIPTOR_TORUS_FIFO_MAP_BP |
        MUHWI_DESCRIPTOR_TORUS_FIFO_MAP_CM |
        MUHWI_DESCRIPTOR_TORUS_FIFO_MAP_CP |
        MUHWI_DESCRIPTOR_TORUS_FIFO_MAP_DM |
        MUHWI_DESCRIPTOR_TORUS_FIFO_MAP_DP |
        MUHWI_DESCRIPTOR_TORUS_FIFO_MAP_EM |
        MUHWI_DESCRIPTOR_TORUS_FIFO_MAP_EP;

    uint64_t offset;
    static int  did_print =0;

    // loop over directions
    // CHECK offset needs to be adjusted for QCD case
    for(unsigned int i = 0; i < num_dirs; i++) {
        // Injection Direct Put Descriptor Information Structure
        MUSPI_Pt2PtDirectPutDescriptorInfo_t dinfo;

        memset( (void*)&dinfo, 0x00, sizeof(dinfo) );

        dinfo.Base.Payload_Address = sendBufPAddr + soffsets[i];
        dinfo.Base.Message_Length  = messageSizes[i];
        dinfo.Base.Torus_FIFO_Map  = anyFifoMap;

        dinfo.Base.Dest = nb2dest[i].dest;

        dinfo.Pt2Pt.Hints_ABCD = nb2dest[i].hintsABCD;

        if(do_dynamic) {
            dinfo.Pt2Pt.Misc1 =
                nb2dest[i].hintsE |
                MUHWI_PACKET_USE_DYNAMIC_ROUTING |
                MUHWI_PACKET_DO_NOT_ROUTE_TO_IO_NODE;

            dinfo.Pt2Pt.Misc2 =
                MUHWI_PACKET_VIRTUAL_CHANNEL_DYNAMIC |
                zoneRoutingMask |
                stayOnBubbleMask;
            if ( (g_cart_id ==0) && (did_print ==0))
                printf("# SPI using dynamic routing  zoneRoutingMask=%d stayOnBubbleMask=%d\n",
                       zoneRoutingMask, stayOnBubbleMask);
        }
        else {
            dinfo.Pt2Pt.Misc1 =
                nb2dest[i].hintsE |
                MUHWI_PACKET_USE_DETERMINISTIC_ROUTING |
                MUHWI_PACKET_DO_NOT_ROUTE_TO_IO_NODE;

            dinfo.Pt2Pt.Misc2 =
                MUHWI_PACKET_VIRTUAL_CHANNEL_DETERMINISTIC |
                zoneRoutingMask |
                stayOnBubbleMask;
            if ( (g_cart_id ==0) && (did_print ==0)) printf("# SPI using deterministic routing\n");
        }
        did_print++;

        dinfo.Pt2Pt.Skip  = 8; // for checksumming, skip the header
        dinfo.DirectPut.Rec_Payload_Base_Address_Id = recvBufBatId;
        dinfo.DirectPut.Rec_Payload_Offset          = roffsets[i];
        dinfo.DirectPut.Rec_Counter_Base_Address_Id = recvCntrBatId;
        dinfo.DirectPut.Rec_Counter_Offset          = 0;

        dinfo.DirectPut.Pacing = MUHWI_PACKET_DIRECT_PUT_IS_NOT_PACED;

        int rc = MUSPI_CreatePt2PtDirectPutDescriptor(&descriptors[i],
                 &dinfo );
        if (rc != 0) {
            fprintf(stderr, "MUSPI_CreatePt2PtDirectPutDescriptor failed with rc=%d\n",rc);
            exit(1);
        }
    }
}