Example #1
0
uint64_t msg_InjFifoInject ( msg_InjFifoHandle_t injFifoHandle,
                             uint32_t            relativeFifoId,
                             MUHWI_Descriptor_t *descPtr ) {
    msg_InjFifoInfo_t *info = (msg_InjFifoInfo_t*)injFifoHandle.pOpaqueObject;

    uint32_t globalFifoId = (info->startingSubgroupId * BGQ_MU_NUM_INJ_FIFOS_PER_SUBGROUP) +
                            info->startingFifoId + relativeFifoId;

    uint32_t subgroupId   = globalFifoId / BGQ_MU_NUM_INJ_FIFOS_PER_SUBGROUP;
    uint64_t rc = MUSPI_InjFifoInject (MUSPI_IdToInjFifo( globalFifoId % BGQ_MU_NUM_INJ_FIFOS_PER_SUBGROUP,
                                       &info->subgroup[subgroupId] ),
                                       descPtr);
    return rc;
}
Example #2
0
  //start spi communication
  void spi_comm_start(comm_t &in,int *dir_comm,int tot_size)
  {
    //reset the counter and wait that all have reset
    spi_global_barrier();
    if(tot_size==-1) spi_recv_counter=in.tot_mess_size;
    else spi_recv_counter=tot_size;
    spi_global_barrier();
    
    //start the injection
    for(int idir=0;idir<8;idir++)
      if(paral_dir[idir%4]&&(dir_comm==NULL||dir_comm[idir]))
	{
	  verbosity_lv3_master_printf("Injecting %d\n",idir);
	  
	  spi_desc_count[idir]=MUSPI_InjFifoInject(MUSPI_IdToInjFifo(idir,&spi_fifo_sg_ptr),&in.descriptors[idir]);
	  if(spi_desc_count[idir]>(1ll<<57)) crash("msg_InjFifoInject returned %llu when expecting 1, most likely because there is no room in the fifo",spi_desc_count[idir]);
	}
  }
Example #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;
}