예제 #1
0
void stdio_init( void )
{
    uartlite_config_t   config1;
    uartlite_config_t   config2;

    if( _get_procid() == 0 )
    {
        // Setup the base address of the UART
        config1.base = UART1_BASEADDR;
    
        // Create the UART Lite device
        uartlite_create( &(_io_uart1), &config1 );

        // Initialize the stdin and stdout flags
        stdin_flags = 0;
        stdout_flags = 0;
    }
    else
    {
        // Setup the base address of the UART
        config2.base = UART2_BASEADDR;
    
        // Create the UART Lite device
        uartlite_create( &(_io_uart2), &config2 );

        // Initialize the stdin and stdout flags
        stdin_flags = 0;
        stdout_flags = 0;
    }
}  
예제 #2
0
void* simple_thread(void * arg) 
{
    struct simple_test * simple;
	
    // Extract thread argument
    simple = (struct simple_test *) arg;

#ifdef PRINT	
    int * pic_0_addr = (void*)0x41200000;
    int * pic_1_addr = (void*)0x41210000;
    printf( "\n..................................\n");
    printf( "simple_thread: CPUID = %d\n", _get_procid());
    printf( "simple_thread: PIC 0 = 0x%8.8x\n",*pic_0_addr);
    printf( "simple_thread: PIC 1 = 0x%8.8x\n",*pic_1_addr);
    printf( "simple_thread: Val =  %d\n", simple->val );
#endif
    
    // Increment value
    simple->val = simple->val + 10; 

#ifdef YIELD    
    hthread_yield();
#endif

#ifdef SELF
    hthread_t self_test = hthread_self();
#ifdef PRINT
    printf("simple_thread: TID VERIFIED %d\n", self_test);
#endif
#endif		

    return (void*)simple->val;
}
예제 #3
0
int main (int argc, char *argv[]) 
{
    unsigned int start      = 0;
    unsigned int stop       = 0;
    hthread_t thread;
    struct simple_test simple;
    Huint i, j, ret;
	
for(j = 0; j < ITERATIONS; j++)
{

#ifdef PRINT	
    printf("\nStarting Simple Test...\n");
#endif	
    simple.val = 110;

    // Xilinx OPB Timer locations as specified in the .mhs file
    volatile int *timer_control = (int*)0x73000000;
    volatile int *timer_value   = (int*)0x73000008;

    // Enable timer and clear interrupt
    *timer_control = 0x00000510;

    // Start the timer
    start = *timer_value;

    for(i = 0; i < j+1; i++)
    {
	hthread_create(&thread, NULL, simple_thread, (void*)&simple); 
        hthread_join(thread, (void*)&ret);

#ifdef PRINT		
        printf( "main: CPUID = %d\n",_get_procid());
        printf( "main: Val =  %d\n", simple.val );
	printf( "..................................\n");
#endif	
    }

    // Stop timer
    stop = *timer_value;
    
    printf("Exec. Time = %d Iteration = %d\n",(stop-start),j);

#ifdef PRINT
    printf("Start Time = %u\n",start);
    printf("Stop Time  = %u\n",stop);
    printf("Exec. Time = %d\n",(stop-start));
    printf( "main: Val =  %d\n", simple.val );
    printf( "- done -\n\n" );
#endif
}
    return 0;
}
예제 #4
0
/**
 * \ingroup rpc
 * \internal
 *
 * This sends a message first created with split_call_begin. The archive
 * pointer is consumed.
 */
  static void split_call_end(dc_dist_object_base* rmi,
                             oarchive* oarc, dc_send* sender, procid_t target, unsigned char flags) {
    // header points to the location of the blob size argument
    size_t blobsize_offset = *reinterpret_cast<size_t*>(oarc->buf);
    (*reinterpret_cast<size_t*>(oarc->buf + blobsize_offset)) = oarc->off - blobsize_offset - sizeof(size_t);
    // write the packet header
    packet_hdr* hdr = reinterpret_cast<packet_hdr*>(oarc->buf);
    hdr->len = oarc->off - sizeof(packet_hdr);
    hdr->src = _get_procid();
    hdr->packet_type_mask = flags;
    hdr->sequentialization_key = _get_sequentialization_key();
    size_t len = hdr->len;
    write_thread_local_buffer(target, oarc->buf, oarc->off, flags & CONTROL_PACKET);
    if ((flags & CONTROL_PACKET) == 0) {
      rmi->inc_bytes_sent(target, len);
    }
    delete oarc;
  }
예제 #5
0
/** \internal
  * \brief  The Hybrid Threads initialization function.
  *
  * This function is the Hybrid Threads initialization function. This function
  * must be called before any other HThread's functionality is used.
  */
void hthread_init( void )
{
    int ret, i;
    hthread_t main_thread;
    hthread_t idle_thread;
    hthread_attr_t attrs;
    Huint status;

#ifdef HTHREADS_SMP
    int cpuid;
    if(_get_procid() == 0)
    {
        /* Default all stack values to NULL */
        for( i = 0; i < MAX_THREADS; i++ )  threads[ i ].stack	= NULL;

        /* Initialize the thread manager */ 
        _init_thread_manager();

        // Have to acknowledge the access interrupt generated because
        // spinlock and semaphore cores cause a failure
        // Hardcoded...FIXME
        intr_ack( 0x41200000, ACCESS_INTR_MASK );
        intr_ack( 0x41210000, ACCESS_INTR_MASK );

        // Must call this function again because we just reset the TM after
        // already reading CPUID = 0, therefore the next call to _init_cpuid()
        // will also return zero, giving two cpu's the id of zero
        _init_cpuid();

        // Setup the attributes for the idle thread
        attrs.detached	  = Htrue;
        attrs.stack_size  = HT_IDLE_STACK_SIZE;
        attrs.hardware    = Hfalse;
        attrs.stack_addr  = (void*)NULL;
        attrs.sched_param = 0x0000007F;           // Worst possible priority

        // Create the idle thread
        _create_system_thread( &idle_thread, &attrs, _idle_thread, NULL );
        TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "HThread Init: (IDLE ID(PPC_%d)=%u)\n", _get_procid(), idle_thread );

        // Tell the hardware what the idle thread is
        _set_idle_thread( idle_thread, _get_procid() );

        //hthread_spin_lock(&(_sysc_lock));

        // Enable PPC specific interrupts
        //_arch_enable_intr();

        // Initialize the Architecture Specific Code
        TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "Initializing Architecture...\n" );
        //_init_arch_specific( idle_thread );
        //_init_arch_specific();

        // Need to acquire lock here because bootstrap releases lock
        while(!_get_syscall_lock());

        _restore_context( 0 , idle_thread );
    }
    else
    {
        // Setup the attributes for the main thread
        attrs.detached	    = Htrue;                // The Main Thread is Detached
        attrs.stack_size    = HT_MAIN_STACK_SIZE;   // Stack Size for Main Thread
        attrs.hardware      = Hfalse;               // The Main Thread is not Hardware
        attrs.stack_addr    = (void*)0xFFFFFFFF;    // The Main Thread Already Has a Stack
        attrs.sched_param   = HT_DEFAULT_PRI;           // Middle of the Road Priority

        // Create the main thread
        _create_system_thread( &main_thread, &attrs, NULL, NULL );
        TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "HThread Init: (MAIN ID(PPC_%d)=%u)\n", _get_procid(), main_thread );

        // Prevent the system from attempting to deallocate the main stack
        threads[ main_thread ].stack = NULL;

        // Add the main thread onto the ready-to-run queue
        status = _add_thread( main_thread );

        // Set the next thread to be the current thread. This should place
        // the main thread into the current thread register.
        status = _next_thread();

        // The main thread is not a new thread	
        threads[ main_thread ].newthread = Hfalse;

        // Setup the attributes for the idle thread
        attrs.detached	    = Htrue;
        attrs.stack_size    = HT_IDLE_STACK_SIZE;
        attrs.hardware      = Hfalse;
        attrs.stack_addr    = (void*)NULL;
        attrs.sched_param   = 0x0000007F;           // Worst possible priority

        // Create the idle thread
        _create_system_thread( &idle_thread, &attrs, _idle_thread, NULL );
        TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "HThread Init: (IDLE ID(PPC_%d)=%u)\n", _get_procid(), idle_thread );

        // Tell the hardware what the idle thread is
        _set_idle_thread( idle_thread, _get_procid() );

        // Enable PPC specific interrupts
        //_arch_enable_intr();

        // Initialize the Architecture Specific Code
        TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "Initializing Architecture...\n" );
        //_init_arch_specific( main_thread );
        //_init_arch_specific();

        // Enter into user mode
        //_arch_enter_user();

        _enable_preemption();
    }
#else
    // Initialize all of the thread stacks to NULL
    TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "Initializing HThreads System...\n" );
    for( i = 0; i < MAX_THREADS; i++ )  threads[ i ].stack	= NULL;

    // Initialize the Thread Manager
    TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "Initializing Thread Manager...\n" );
    _init_thread_manager();

    // Setup the attributes for the main thread
    attrs.detached	= Htrue;                // Main thread is detached
    attrs.stack_size	= HT_MAIN_STACK_SIZE;   // Stack size for main thread
    attrs.hardware      = Hfalse;               // Main thread is not hardware
    attrs.stack_addr    = (void*)0xFFFFFFFF;    // Main thread has a stack
    attrs.sched_param   = HT_DEFAULT_PRI;      // Middle of the road priority

    // Create the main thread
    ret = _create_system_thread( &main_thread, &attrs, NULL, NULL );
    TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "HThread Init: (MAIN ID=%u)\n", main_thread );
    if( ret != SUCCESS )
    {
        TRACE_PRINTF(TRACE_FATAL, TRACE_INIT, "HThread Init: create main thread failed\n" );
        while(1);
    }

    // Initialize the Architecture Specific Code
    TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "Initializing Architecture...\n" );
    
    //_init_arch_specific();

    // Prevent the system from attempting to deallocate the main stack
    threads[ main_thread ].stack = NULL;

    // Add the main thread onto the ready-to-run queue
    status = _add_thread( main_thread );

    // Set the next thread to be the current thread. This should place
    // the main thread into the current thread register.
    status = _next_thread();

    // Setup the attributes for the idle thread
    attrs.detached	= Htrue;
    attrs.stack_addr    = (void*)NULL;
    attrs.stack_size	= HT_IDLE_STACK_SIZE;

    // Create the idle thread
    ret = _create_system_thread( &idle_thread, &attrs, _idle_thread, NULL );
    TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "HThread Init: (IDLE ID=%u)\n", idle_thread );
    if( ret != SUCCESS )
    {
        TRACE_PRINTF(TRACE_FATAL, TRACE_INIT, "HThread Init: create idle thread failed\n" );
        while(1);
    }

    // Tell the hardware what the idle thread is
    // FIXME - The CPUID is hardcoded, fix the manager/hardware.h file!
    _set_idle_thread( idle_thread , 0);

    // The main thread is not a new thread	
    threads[ main_thread ].newthread = Hfalse;

    // Enter into user mode
    //_arch_enable_intr();
    //_arch_enter_user();
#endif
}
예제 #6
0
///////////////////////////////////////////////////////////////////////////////
// This function gets a command index with the hba_cmd_alloc function. Then it
// registers a command in both the command list and the command table. It
// updates the HBA_PXCI register and the hba_active_cmd in descheduling mode.
// At the end the command slot is released.
// return 0 if success, -1 if error
///////////////////////////////////////////////////////////////////////////////
unsigned int _hba_access( unsigned int       use_irq,
                          unsigned int       to_mem,
                          unsigned int       lba,  
                          unsigned long long buf_paddr,
                          unsigned int       count )   
{
    unsigned int procid  = _get_procid();
    unsigned int x       = procid >> (Y_WIDTH + P_WIDTH);
    unsigned int y       = (procid >> P_WIDTH) & ((1<<Y_WIDTH) - 1);
    unsigned int p       = procid & ((1<<P_WIDTH)-1);

#if GIET_DEBUG_IOC
if (_get_proctime() > GIET_DEBUG_IOC)
_printf("\n[DEBUG HBA] _hba_access() : P[%d,%d,%d] enters at cycle %d\n"
        "  use_irq = %d / to_mem = %d / lba = %x / paddr = %l / count = %d\n",
        x , y , p , _get_proctime() , use_irq , to_mem , lba , buf_paddr, count );
#endif

    unsigned int       cmd_id;            // command index
    unsigned int       pxci;              // HBA_PXCI register value
    unsigned int       pxis;              // HBA_PXIS register value
    hba_cmd_desc_t*    cmd_desc;          // command descriptor pointer   
    hba_cmd_table_t*   cmd_table;         // command table pointer

    // check buffer alignment
    if( buf_paddr & 0x3F )
    {
        _printf("\n[HBA ERROR] in _hba_access() : buffer not 64 bytes aligned\n");
        return -1;
    }

    // get one entry in Command List
    cmd_id = _hba_cmd_alloc();

    // compute pointers on command descriptor and command table    
    cmd_desc  = &_hba_cmd_list[cmd_id];
    cmd_table = &_hba_cmd_table[cmd_id];

    // set  buffer descriptor in command table 
    cmd_table->buffer.dba  = (unsigned int)(buf_paddr);
    cmd_table->buffer.dbau = (unsigned int)(buf_paddr >> 32);
    cmd_table->buffer.dbc  = count * 512;

    // initialize command table header
    cmd_table->header.lba0 = (char)lba;
    cmd_table->header.lba1 = (char)(lba>>8);
    cmd_table->header.lba2 = (char)(lba>>16);
    cmd_table->header.lba3 = (char)(lba>>24);
    cmd_table->header.lba4 = 0;
    cmd_table->header.lba5 = 0;

    // initialise command descriptor
    cmd_desc->prdtl[0] = 1;
    cmd_desc->prdtl[1] = 0;
    if( to_mem ) cmd_desc->flag[0] = 0x00;
    else         cmd_desc->flag[0] = 0x40;     

#if USE_IOB    // software L2/L3 cache coherence

    // compute physical addresses
    unsigned long long cmd_desc_paddr;    // command descriptor physical address
    unsigned long long cmd_table_paddr;   // command table header physical address
    unsigned int       flags;             // unused

    if ( _get_mmu_mode() & 0x4 )
    {
        cmd_desc_paddr  = _v2p_translate( (unsigned int)cmd_desc  , &flags );
        cmd_table_paddr = _v2p_translate( (unsigned int)cmd_table , &flags );
    }
    else
    {
        cmd_desc_paddr  = (unsigned int)cmd_desc;
        cmd_table_paddr = (unsigned int)cmd_table;
    }

    // update external memory for command table 
    _mmc_sync( cmd_table_paddr & (~0x3F) , sizeof(hba_cmd_table_t) );

    // update external memory for command descriptor
    _mmc_sync( cmd_desc_paddr & (~0x3F) , sizeof(hba_cmd_desc_t) );

    // inval or synchronize memory buffer
    if ( to_mem )  _mmc_inval( buf_paddr, count<<9 );
    else           _mmc_sync( buf_paddr, count<<9 );

#endif     // end software L2/L3 cache coherence

    /////////////////////////////////////////////////////////////////////
    // In synchronous mode, we poll the PXCI register until completion
    /////////////////////////////////////////////////////////////////////
    if ( use_irq == 0 ) 
    {
        // start HBA transfer
        _hba_set_register( HBA_PXCI, (1<<cmd_id) );

#if GIET_DEBUG_IOC
if (_get_proctime() > GIET_DEBUG_IOC)
_printf("\n[DEBUG HBA] _hba_access() : P[%d,%d,%d] get slot %d in Cmd List "
        " at cycle %d / polling\n",
        x , y , p , cmd_id, _get_proctime() );
#endif
        // disable IRQs in PXIE register
        _hba_set_register( HBA_PXIE , 0 );

        // poll PXCI[cmd_id] until command completed by HBA
        do
        {
            pxci = _hba_get_register( HBA_PXCI );

#if GIET_DEBUG_IOC
if (_get_proctime() > GIET_DEBUG_IOC)
_printf("\n[DEBUG HBA] _hba_access() : P[%d,%d,%d] wait on HBA_PXCI / pxci = %x\n",
        x , y , p , pxci );
#endif
        }
        while( pxci & (1<<cmd_id) ); 
             
        // get PXIS register
        pxis = _hba_get_register( HBA_PXIS );

        // reset PXIS register
        _hba_set_register( HBA_PXIS , 0 );
    }

    /////////////////////////////////////////////////////////////////
    // in descheduling mode, we deschedule the task
    // and use an interrupt to reschedule the task.
    // We need a critical section, because we must set the NORUN bit
	// before to launch the transfer, and we don't want to be 
    // descheduled between these two operations. 
    /////////////////////////////////////////////////////////////////
    else
    {

#if GIET_DEBUG_IOC
if (_get_proctime() > GIET_DEBUG_IOC)
_printf("\n[DEBUG HBA] _hba_access() : P[%d,%d,%d] get slot %d in Cmd List "
        "at cycle %d / descheduling\n",
        x , y , p , cmd_id, _get_proctime() );
#endif
        unsigned int save_sr;
        unsigned int ltid = _get_current_task_id();

        // activates HBA interrupts 
        _hba_set_register( HBA_PXIE , 0x00000001 ); 

        // set _hba_gtid[cmd_id] 
        _hba_gtid[cmd_id] = (procid<<16) + ltid;

        // enters critical section
        _it_disable( &save_sr ); 

        // Set NORUN_MASK_IOC bit 
        static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p];
        unsigned int*       ptr     = &psched->context[ltid][CTX_NORUN_ID];
        _atomic_or( ptr , NORUN_MASK_IOC );
      
        // start HBA transfer
        _hba_set_register( HBA_PXCI, (1<<cmd_id) );

        // set _hba_active_cmd[cmd_id]
        _hba_active_cmd[cmd_id] = 1;

        // deschedule task
        _ctx_switch();                      

#if GIET_DEBUG_IOC
if (_get_proctime() > GIET_DEBUG_IOC)
_printf("\n[DEBUG HBA] _hba_access() : task %d on P[%d,%d,%d] resume at cycle %d\n",
        ltid , x , y , p , _get_proctime() );
#endif

        // restore SR
        _it_restore( &save_sr );

        // get command status
        pxis = _hba_status;
    }
    
    // release the cmd index
    unsigned int release_success;
    release_success = _hba_cmd_release(cmd_id);

#if GIET_DEBUG_IOC
if (_get_proctime() > GIET_DEBUG_IOC)
_printf("\n[DEBUG HBA] _hba_access() : P[%d,%d,%d] release slot %d in Cmd List "
        "and exit at cycle %d\n",
        x , y , p, cmd_id,
        _get_proctime() );
#endif

    if ( release_success != 0 )   return -1;
    else if ( pxis & 0x40000000 ) return pxis;
    else                          return 0;

} // end _hba_access()