Exemple #1
0
static errno_t threads_test()
{

    hal_cond_init(&c, "threadTest");
    hal_mutex_init(&m, "threadTest");
    hal_sem_init(&s, "threadTest");

    int i = 40;
    n_t_empty = i;
    while(i-- > 0)
        phantom_create_thread( t_empty, "Empty", 0 );

    pressEnter("will create thread");
    phantom_create_thread( thread1, "__T1__", 0 );
    phantom_create_thread( thread1, "__T2__", 0 );
    //phantom_create_thread( thread1, "__T3__" );

    //phantom_create_thread( t_wait, "__TW__" );
    int tid = hal_start_kernel_thread_arg( t_wait, "__TW__" );

    i = 40;
    while(i-- > 0)
    {
        if(TEST_CHATTY) pressEnter("will yield");
        YIELD();

        if(TEST_CHATTY) printf("!! back in main\n");
    }

    t_kill_thread( tid );
    hal_sleep_msec( 30 );

    thread_stop_request = 1;
    hal_sleep_msec( 10 );

    thread_activity_counter = 0;
    hal_sleep_msec( 1000 );
    if( thread_activity_counter )
    {
        SHOW_ERROR0( 0, "Can't stop thread" );
        return -1;
    }

    while(n_t_empty > 0)
    {
        SHOW_FLOW( 0, "wait for %d threads", n_t_empty );
        hal_sleep_msec(500);
    }

    if(p._ah.refCount != 1)
    {
        SHOW_ERROR( 0, "p._ah.refCount = %d", p._ah.refCount );
        test_fail_msg( -1, "refcount" );
    }
    else
        SHOW_ERROR( 0, "p._ah.refCount = %d, SUCCESS", p._ah.refCount );

    return 0;
}
Exemple #2
0
int do_test_sem(const char *test_parm)
{
    (void) test_parm;
    printf("Testing semaphores\n");

    hal_sem_init(&test_sem_0, "semTest");



    softirq = hal_alloc_softirq();
    if( softirq < 0 )
        test_fail_msg( 1, "Unable to get softirq" );

    hal_set_softirq_handler( softirq, sem_softirq, 0 );

    //int tid =
    hal_start_kernel_thread_arg( sem_rel, 0 );

    printf("sema wait 1\n");

    // Direct
    sem_released = 0;
    hal_sem_acquire( &test_sem_0 );
    test_check_eq(sem_released,1);

    hal_sleep_msec( 100 );

    printf("sema wait 2\n");

#if TEST_SOFTIRQ
    // Softirq
    sem_released = 0;
    hal_sem_acquire( &test_sem_0 );
    test_check_eq(sem_released,1);
#endif

    hal_sleep_msec( 100 );


    printf("sema timeout\n");
    sem_released = 0;
    hal_start_kernel_thread_arg( sem_etc, 0 );
    hal_sleep_msec( 100 );
    test_check_eq(sem_released,0);
    hal_sleep_msec( 120 );
    test_check_eq(sem_released,1);
    test_check_eq( rc, ETIMEDOUT);


    stop_sem_test = 1;

    printf("Done testing semaphores\n");
    return 0;

}
Exemple #3
0
static void trfs_recv_thread(void *arg)
{
    (void) arg;

    u_int8_t    buf[TRFS_MAX_PKT];

    t_current_set_name("TRFS Recv");

    while(connect_trfs())
    {
        SHOW_ERROR0( 1, "Unable to connect" );
        hal_sleep_msec(20000);
        //return;
    }
    while(1)
    {
        int rc;
        if( ( rc = trfs_recv( &buf, TRFS_MAX_PKT)) <= 0 )
        {
            SHOW_ERROR( 1, "recv err %d", rc );
        again:
            hal_sleep_msec( 100 ); // Against tight loop
            continue;
        }

        if( rc < (int)sizeof(trfs_pkt_t) )
        {
            SHOW_ERROR( 1, "recv pkt size %d < required %d", rc, sizeof(trfs_pkt_t) );
            goto again;
        }

        trfs_pkt_t *rq = (trfs_pkt_t *)buf;

        SHOW_FLOW( 6, "got pkt type %d", rq->type );

        if(rq->sessionId != sessionId)
        {
            trfs_reset_session(rq->sessionId);
            if(rq->type != PKT_T_Error)
                continue;
        }

        switch(rq->type)
        {
        case PKT_T_Error:    		recvError(rq);          break;
    	case PKT_T_ReadReply:        	recvReadReply(rq);      break;
    	case PKT_T_FindReply:        	recvFindReply(rq);      break;

        default:
            SHOW_ERROR( 0, "TRFS: unknown packet type %d", rq->type);

        }
    }
}
Exemple #4
0
static void trfs_resend_thread(void *arg)
{
    (void) arg;

    t_current_set_name("TRFS Resend");

    while(1)
    {
        hal_sleep_msec( 1000 ); // between bursts
        hal_mutex_lock(&lock);

        trfs_queue_t *first = 0;

    again:
        if(queue_empty(&requests))
        {
            hal_mutex_unlock(&lock);
            continue;
        }

        trfs_queue_t *elt;

        // Move to end
        queue_remove_first( &requests, elt, trfs_queue_t *, chain );
        queue_enter(&requests, elt, trfs_queue_t *, chain);

        if( elt == first )
        {
            hal_mutex_unlock(&lock);
            continue;
        }
        first = elt;

        if( TRFS_NEED_RESEND(elt) )
        {
            if( elt->resend_count++ > MAX_RETRY )
            {
                queue_remove( &requests, elt, trfs_queue_t *, chain );
                //elt->orig_request->flag_ioerror = 1;
                elt->orig_request->rc = ETIMEDOUT;
                trfs_signal_done(elt);
            }
            else
            {
                SHOW_FLOW0( 1, "rerequest" );
                sendRequest(elt);
                hal_sleep_msec( 100 ); // between packets
            }
            goto again;
        }
int phantom_dev_keyboard_get_key(void)
{
//#warning completely wrong!!!
    //    return debug_console_getc();
    while(1)
        hal_sleep_msec(10000);
}
void
disk_page_io_wait(disk_page_io *me)
{

#if 0
    // BUG! RACES!
    while( req.flag_pagein || req.flag_pageout )
        hal_sleep( &req );
#else
    // BUG! polling!
    hal_sleep_msec( 1 ); 
    //phantom_scheduler_yield();
    while( me->req.flag_pagein || me->req.flag_pageout )
        hal_sleep_msec( 10 );
#endif
}
Exemple #7
0
void dpc_init()
{
    SHOW_FLOW0( 1, "Starting DPC");
    hal_cond_init( &dpc_thread_sleep_stone, "DPC" );
    spinlock_init( &dpc_request_lock );

    hal_mutex_init(&unused_dpc_mutex, "DPC");

    SHOW_FLOW0( 1, "Starting DPC thread...");
    //dpc_thread_object =
    hal_start_kernel_thread(dpc_thread);

#if !DPC_WAKE_TIMER
    SHOW_FLOW0( 1, " starting DPC waker thread...");
    //dpc_timed_waker_thread_object =
    hal_start_kernel_thread(dpc_timed_waker_thread);
#else
    dpc_timer_wake(0);
#endif

    while(!dpc_init_ok)
    {
        SHOW_FLOW0( 2, " wait for DPC threads...");
        hal_sleep_msec(1); // wait for thread to start
    }

    SHOW_FLOW0( 0, "DPC start done");
}
Exemple #8
0
static void dpc_serve1( void *arg )
{
    if( strcmp( arg, DPC_ARG1 ) )
    {
        SHOW_ERROR0( 0, "DPC 1 arg is wrong" );
        test_fail( -1 );
    }

    dpc1_triggered = 1;
    hal_sleep_msec(2000);
}
Exemple #9
0
static void dpc_timed_waker_thread(void)
{
    hal_set_thread_name("DPC Waker");

    while(1)
    {
        hal_sleep_msec(1000);
        if(dpc_stop_request)
            hal_exit_kernel_thread();

        dpc_timed();
    }
}
Exemple #10
0
static void sem_rel(void *a)
{
    (void) a;
    hal_sleep_msec( 300 );
    printf("sema release 1 (direct)\n");
    sem_released = 1;
    hal_sem_release( &test_sem_0 );

#if TEST_SOFTIRQ
    hal_sleep_msec( 300 );
    printf("sema release 2 (softirq %d)\n", softirq );
    sem_released = 1;
    hal_request_softirq( softirq );
#endif
    /*
    while(!stop_sem_test)
    {
        hal_sleep_msec( 500 );
    }

    */
}
Exemple #11
0
void phantom_finish_all_threads(void)
{
    phantom_virtual_machine_stop_request = 1;
    phantom_virtual_machine_snap_request = 1;

    SHOW_FLOW( 2, "Finishing %d threads", n_vm_threads);
    while(n_vm_threads > 0)
    {
        SHOW_FLOW( 6, "Waiting for threads to finish, %d left", n_vm_threads);
        hal_sleep_msec(1);
        // For snapper may, possibly, decrement it till then
        phantom_virtual_machine_snap_request = 1;
    }
}
Exemple #12
0
static void stray_catch_thread(void)
{
    hal_set_thread_name("StrayCheck");
    printf("Stray checker running, %d windows\n", ncr);

    while(1)
    {
        // 1 sec
        //hal_sleep_msec(1000);
        hal_sleep_msec(50);

        stray();
    }
}
Exemple #13
0
static void start_new_vm_thread(struct pvm_object new_thread)
{
    args_used++;

    //int tid = hal_start_thread(thread_run_func, &new_thread, THREAD_FLAG_VM|THREAD_FLAG_USER);
    int tid = hal_start_thread(thread_run_func, &new_thread, THREAD_FLAG_VM);

    struct data_area_4_thread *tda = pvm_object_da( new_thread, thread );
    tda->tid = tid;

    t_set_owner( tid, new_thread.data );
    //phantom_thread_t *t = get_thread(tid);
    //t->owner = new_thread.data;

    while(args_used > 0)
        hal_sleep_msec(1);

    if(tda->sleep_flag)
    {
        //timedcall_t *e = &(tda->timer);
        net_timer_event *e = &(tda->timer);

        int didit = 0;

        if( e->pending )
        {
            bigtime_t msecMore = e->sched_time - hal_system_time();

            msecMore /= 1000;

            if( msecMore > 0 )
            {
                // Thread is sleeping on timer, reactivate wakeup
                phantom_wakeup_after_msec( msecMore, tda );
            }
            else
            {
                // Sleep time is passed, just wake
                SYSCALL_WAKE_THREAD_UP(tda);
            }
            didit = 1;
        }

        if(!didit)
        {
            SHOW_ERROR( 0, "Sleeping VM thread has no means to wakeup (%p)", new_thread.data );
        }

    }
}
Exemple #14
0
static void thread_ones(void *a)
{
    (void) a;

    register int a01 = 1;
    register int a02 = 1;
    register int a03 = 1;
    register int a04 = 1;
    register int a05 = 1;
    register int a06 = 1;
    register int a07 = 1;
    register int a08 = 1;
    register int a09 = 1;
    register int a10 = 1;


    int c = 2000;
    while( c-- > 0 )
    {
        hal_sleep_msec(1);

        zo_check_eq(a01,1);
        zo_check_eq(a02,1);
        zo_check_eq(a03,1);
        zo_check_eq(a04,1);
        zo_check_eq(a05,1);
        zo_check_eq(a06,1);
        zo_check_eq(a07,1);
        zo_check_eq(a08,1);
        zo_check_eq(a09,1);
        zo_check_eq(a10,1);
    }

    zo_run--;

    hal_sleep_msec(10000);
}
Exemple #15
0
static void thread_zeroes(void *a)
{
    (void) a;

    register int a01 = 0;
    register int a02 = 0;
    register int a03 = 0;
    register int a04 = 0;
    register int a05 = 0;
    register int a06 = 0;
    register int a07 = 0;
    register int a08 = 0;
    register int a09 = 0;
    register int a10 = 0;


    int c = 2000;
    while( c-- > 0 )
    {
        hal_sleep_msec(1);

        zo_check_eq(a01,0);
        zo_check_eq(a02,0);
        zo_check_eq(a03,0);
        zo_check_eq(a04,0);
        zo_check_eq(a05,0);
        zo_check_eq(a06,0);
        zo_check_eq(a07,0);
        zo_check_eq(a08,0);
        zo_check_eq(a09,0);
        zo_check_eq(a10,0);
    }

    zo_run--;
    hal_sleep_msec(10000);
}
static int phantom_window_getc(void)
{
    //SHOW_FLOW0( 11, "window getc" );
    //wtty_t *tty = &(GET_CURRENT_THREAD()->ctty);
#if CONF_NEW_CTTY
    wtty_t *tty = GET_CURRENT_THREAD()->ctty_w;
#else
    wtty_t *tty = GET_CURRENT_THREAD()->ctty;
#endif
    if(tty == 0)
    {
        SHOW_ERROR0( 0, "No wtty, phantom_window_getc loops forever" );
        while(1)
            hal_sleep_msec(10000);
    }

    return wtty_getc( tty );
}
Exemple #17
0
int do_test_01_threads(const char *test_parm)
{
    (void) test_parm;
    printf("Testing thread state integrity\n");

    hal_start_kernel_thread_arg( thread_ones, 0 );
    hal_start_kernel_thread_arg( thread_zeroes, 0 );

    printf("Wait for 01 threads to finish\n");

    while(zo_run)
        hal_sleep_msec(100);


    if(zo_fail)
        test_fail_msg( -1, "data corruption" );

    return 0;
}
Exemple #18
0
static void t_empty(void *a)
{
    (void) a;

    ref_inc_p(&p);

    hal_sleep_msec( random() % 6000 );
    // TODO do some random things, such as sleep, set timer, etc

    ref_inc_p(&p);
    ref_inc_p(&p);
    ref_inc_p(&p);

    ref_dec_p(&p);
    ref_dec_p(&p);
    ref_dec_p(&p);
    ref_dec_p(&p);

    n_t_empty--;
}
//! This thread delivers events from main Q to windows
static void ev_push_thread()
{
    t_current_set_name("UIEventQ");
    // +1 so that it is a bit higher than regular sys threads
    t_current_set_priority(PHANTOM_SYS_THREAD_PRIO+1);

#if EVENTS_ENABLED && 1
    while(1)
    {
        ev_remove_extra_unused();

        struct ui_event *e;

        hal_mutex_lock( &ev_main_q_mutex );
        while(queue_empty(&ev_main_event_q))
            hal_cond_wait( &ev_have_event, &ev_main_q_mutex );

        if(queue_empty(&ev_main_event_q))
            panic("out of events");

        queue_remove_first(&ev_main_event_q, e, struct ui_event *, echain);
        ev_events_in_q--;
        hal_mutex_unlock( &ev_main_q_mutex );

        SHOW_FLOW(8, "%p", e);

        // Deliver to 'em
        ev_push_event(e);

        // window code will return when done
        //return_unused_event(e);
    }
#else
    while(1)
    {
    	hal_sleep_msec(20000);
    }
#endif


}
Exemple #20
0
errno_t disk_fence( struct phantom_disk_partition *p )
{
    assert(p);

    if( 0 == p->fence )
    {
        SHOW_ERROR( 0, "no fence on part %s", p->name );
        return ENODEV;
    }

    errno_t rc = p->fence( p );

    if( rc )
    {
        SHOW_ERROR( 0, "fence failed on part %s, rc %d", p->name, rc );
        hal_sleep_msec( 10000 ); // At least - some chance...
    }


    return rc;
}
static void net_timer_runner(void *arg)
{
    (void) arg;

    net_timer_event *e;
    bigtime_t now;

    t_current_set_name("Net Timer");

    for(;;) {
        //sem_acquire_etc(net_q.wait_sem, 1, SEM_FLAG_TIMEOUT, NET_TIMER_INTERVAL, NULL);
        hal_sleep_msec(NET_TIMER_INTERVAL);

        now = system_time();
//printf("(^)");
    retry:
        mutex_lock(&net_q.lock);

        // pull off the head of the list and run it, if it timed out
        if((e = peek_queue_head()) != NULL && e->sched_time <= now) {

            remove_from_queue(e);
            e->pending = false;

            mutex_unlock(&net_q.lock);

            e->func(e->args);

            // Since we ran an event, loop back and check the head of
            // the list again, because the list may have changed while
            // inside the callback.
            goto retry;

        } else {
            mutex_unlock(&net_q.lock);
        }
    }

}
phantom_device_t * driver_rtl_8169_probe( pci_cfg_t *pci, int stage )
{
    (void) stage;
    rtl8169 * nic = NULL;
    static int seq_number = 0;

return 0; // on real hw beheaves strangely

    SHOW_FLOW0( 1, "probe" );

    //nic = rtl8169_new();
    nic = calloc(1, sizeof(rtl8169));
    if (nic == NULL)
    {
        SHOW_ERROR0( 0, "out of mem");
        return 0;
    }

    nic->irq = pci->interrupt;

    int i;
    for (i = 0; i < 6; i++)
    {
        if (pci->base[i] > 0xffff)
        {
            nic->phys_base = pci->base[i];
            nic->phys_size = pci->size[i];
            SHOW_INFO( 0,  "base 0x%lx, size 0x%lx", nic->phys_base, nic->phys_size );
        } else if( pci->base[i] > 0) {
            nic->io_port = pci->base[i];
            SHOW_INFO( 0,  "io_port 0x%x", nic->io_port );
        }
    }

#if 0
    SHOW_FLOW0( 1, "stop" );
    rtl8169_stop(nic);
    hal_sleep_msec(10);
#endif

    SHOW_FLOW0( 1, "init");
    if (rtl8169_init(nic) < 0)
    {
        SHOW_ERROR0( 0, "init failed");
        return 0;
    }



    phantom_device_t * dev = malloc(sizeof(phantom_device_t));
    dev->name = "rtl8169";
    dev->seq_number = seq_number++;
    dev->drv_private = nic;

    dev->dops.read = rtl8169_read;
    dev->dops.write = rtl8169_write;
    dev->dops.get_address = rtl8169_get_address;

    ifnet *interface;
    if( if_register_interface( IF_TYPE_ETHERNET, &interface, dev) )
    {
        SHOW_ERROR( 0,  "Failed to register interface for %s", dev->name );
    }
    else
    {
        if_simple_setup( interface, WIRED_ADDRESS, WIRED_NETMASK, WIRED_BROADCAST, WIRED_NET, WIRED_ROUTER, DEF_ROUTE_ROUTER );
    }

    return dev;

}
static int rtl8169_init(rtl8169 *r)
{
    //bigtime_t time;
    int err = -1;
    //addr_t temp;
    //int i;

    hal_mutex_init(&r->lock,DEBUG_MSG_PREFIX);


    SHOW_FLOW(2, "rtl8169_init: r %p\n", r);

    /*
     r->region = vm_map_physical_memory(vm_get_kernel_aspace_id(), "rtl8169_region", (void **)&r->virt_base, REGION_ADDR_ANY_ADDRESS, r->phys_size, LOCK_KERNEL|LOCK_RW, r->phys_base);
    if(r->region < 0) {
        SHOW_ERROR0(1, "rtl8169_init: error creating memory mapped region\n");
        err = -1;
        goto err;
    }*/

    size_t n_pages = BYTES_TO_PAGES(r->phys_size);

    hal_alloc_vaddress( (void **)&r->virt_base, n_pages); // alloc address of a page, but not memory
    hal_pages_control_etc( r->phys_base, (void *)r->virt_base, n_pages, page_map_io, page_rw, 0 );

    SHOW_INFO(2, "rtl8169 mapped at address 0x%lx\n", r->virt_base);

#if 0
    /* create regions for tx and rx descriptors */
    r->rxdesc_region = vm_create_anonymous_region(vm_get_kernel_aspace_id(), "rtl8169_rxdesc", (void **)&r->rxdesc,
                                                  REGION_ADDR_ANY_ADDRESS, NUM_RX_DESCRIPTORS * DESCRIPTOR_LEN, REGION_WIRING_WIRED_CONTIG, LOCK_KERNEL|LOCK_RW);
    r->rxdesc_phys = vtophys(r->rxdesc);
    SHOW_INFO(2, "rtl8169: rx descriptors at %p, phys 0x%x\n", r->rxdesc, r->rxdesc_phys);
    r->txdesc_region = vm_create_anonymous_region(vm_get_kernel_aspace_id(), "rtl8169_txdesc", (void **)&r->txdesc,
                                                  REGION_ADDR_ANY_ADDRESS, NUM_TX_DESCRIPTORS * DESCRIPTOR_LEN, REGION_WIRING_WIRED_CONTIG, LOCK_KERNEL|LOCK_RW);
    r->txdesc_phys = vtophys(r->txdesc);
    SHOW_INFO(2, "rtl8169: tx descriptors at %p, phys 0x%x\n", r->txdesc, r->txdesc_phys);
    r->reg_spinlock = 0;

    /* create a large tx and rx buffer for the descriptors to point to */
    r->rxbuf_region = vm_create_anonymous_region(vm_get_kernel_aspace_id(), "rtl8169_rxbuf", (void **)&r->rxbuf,
                                                 REGION_ADDR_ANY_ADDRESS, NUM_RX_DESCRIPTORS * BUFSIZE_PER_FRAME, REGION_WIRING_WIRED, LOCK_KERNEL|LOCK_RW);
    r->txbuf_region = vm_create_anonymous_region(vm_get_kernel_aspace_id(), "rtl8169_txbuf", (void **)&r->txbuf,
                                                 REGION_ADDR_ANY_ADDRESS, NUM_TX_DESCRIPTORS * BUFSIZE_PER_FRAME, REGION_WIRING_WIRED, LOCK_KERNEL|LOCK_RW);
#endif

    hal_pv_alloc( &r->rxdesc_phys, (void**)&r->rxdesc, NUM_RX_DESCRIPTORS * DESCRIPTOR_LEN );
    hal_pv_alloc( &r->txdesc_phys, (void**)&r->txdesc, NUM_TX_DESCRIPTORS * DESCRIPTOR_LEN );

    SHOW_INFO(2, "rx descriptors at %p, phys 0x%x\n", r->rxdesc, r->rxdesc_phys);
    SHOW_INFO(2, "tx descriptors at %p, phys 0x%x\n", r->txdesc, r->txdesc_phys);

    hal_pv_alloc( &r->rxbuf_phys, (void**)&r->rxbuf, NUM_RX_DESCRIPTORS * BUFSIZE_PER_FRAME );
    hal_pv_alloc( &r->txbuf_phys, (void**)&r->txbuf, NUM_TX_DESCRIPTORS * BUFSIZE_PER_FRAME );

    /* create a receive sem */
    hal_sem_init( &r->rx_sem, "rtl8169 rx_sem");

    /* transmit sem */
    hal_sem_init(  &r->tx_sem, "rtl8169 tx_sem");

    /* reset the chip */
    int repeats = 100;
    RTL_WRITE_8(r, REG_CR, (1<<4)); // reset the chip, disable tx/rx
    do {
        hal_sleep_msec(10); // 10ms
        if(repeats -- <= 0 )
            break;
    } while(RTL_READ_8(r, REG_CR) & (1<<4));

    /* read in the mac address */
    r->mac_addr[0] = RTL_READ_8(r, REG_IDR0);
    r->mac_addr[1] = RTL_READ_8(r, REG_IDR1);
    r->mac_addr[2] = RTL_READ_8(r, REG_IDR2);
    r->mac_addr[3] = RTL_READ_8(r, REG_IDR3);
    r->mac_addr[4] = RTL_READ_8(r, REG_IDR4);
    r->mac_addr[5] = RTL_READ_8(r, REG_IDR5);
    SHOW_INFO(2, "rtl8169: mac addr %x:%x:%x:%x:%x:%x\n",
              r->mac_addr[0], r->mac_addr[1], r->mac_addr[2],
              r->mac_addr[3], r->mac_addr[4], r->mac_addr[5]);

    /* some voodoo from BSD driver */
    RTL_WRITE_16(r, REG_CCR, RTL_READ_16(r, REG_CCR));
    RTL_SETBITS_16(r, REG_CCR, 0x3);

    /* mask all interrupts */
    RTL_WRITE_16(r, REG_IMR, 0);

    /* set up the tx/rx descriptors */
    rtl8169_setup_descriptors(r);

    /* enable tx/rx */
    RTL_SETBITS_8(r, REG_CR, (1<<3)|(1<<2));

    /* set up the rx state */
    /* 1024 byte dma threshold, 1024 dma max burst, CRC calc 8 byte+, accept all packets */
    RTL_WRITE_32(r, REG_RCR, (1<<16) | (6<<13) | (6<<8) | (0xf << 0));
    RTL_SETBITS_16(r, REG_CCR, (1<<5)); // rx checksum enable
    RTL_WRITE_16(r, REG_RMS, 1518); // rx mtu

    /* set up the tx state */
    RTL_WRITE_32(r, REG_TCR, (RTL_READ_32(r, REG_TCR) & ~0x1ff) | (6<<8)); // 1024 max burst dma
    RTL_WRITE_8(r, REG_MTPS, 0x3f); // max tx packet size (must be careful to not actually transmit more than mtu)

    /* set up the interrupt handler */
    //int_set_io_interrupt_handler(r->irq, &rtl8169_int, r, "rtl8169");
    if(hal_irq_alloc( r->irq, &rtl8169_int, r, HAL_IRQ_SHAREABLE ))
    {
        SHOW_ERROR( 0, "unable to allocate irq %d", r->irq );
        goto err1;
    }

    /* clear all pending interrupts */
    RTL_WRITE_16(r, REG_ISR, 0xffff);

    /* unmask interesting interrupts */
    RTL_WRITE_16(r, REG_IMR, IMR_SYSERR | IMR_LINKCHG | IMR_TER | IMR_TOK | IMR_RER | IMR_ROK | IMR_RXOVL);

    return 0;

err1:
    // TODO free what?
    //vm_delete_region(vm_get_kernel_aspace_id(), r->region);
//err:
    return err;
}
void run_test( const char *test_name, const char *test_parm )
{
    int all = 0 == strcmp(test_name, "all" );
    //int i;

#ifndef ARCH_ia32
    printf("sleeping 20 sec");
    hal_sleep_msec(200000);
#endif

    printf("Phantom ver %s svn %s test suite\n-----\n", PHANTOM_VERSION_STR, svn_version() );

    TEST(misc);

    TEST(crypt);

    // moved here to test first - rewritten
    TEST(ports);


    // TODO mem leak! out of mem for 200!
    //for( i = 200; i; i-- )
    {
        TEST(sem);
    }

    TEST(wtty);

    TEST(pool);

    // check if starting many threads eats memory
    //for( i = 200; i; i-- )
    {
        TEST(many_threads);
    }

#ifdef ARCH_mips
//    TEST(sem);
    TEST(01_threads);
#endif

    TEST(physmem);
    TEST(physalloc_gen);
    TEST(malloc);
    TEST(amap);

    TEST(cbuf);
    TEST(udp_send);
    TEST(udp_syslog);
    TEST(resolver);

    TEST(tftp);


    TEST(tcp_connect);


    // These are long
    TEST(dpc);
    TEST(timed_call);

    // must test after timed calls for it depends on them
    TEST(ports);


    // These are very long, do 'em last
    TEST(threads);

    TEST(absname);

#ifndef ARCH_ia32
//    TEST(sem);
    TEST(01_threads);
#endif

    TEST(rectangles);
    TEST(video);


    //TEST(video);

    //TEST(userland);

    printf("\n-----\n" );
    if(nFailed)
        printf("some tests FAILED\n" );
    else
        printf("all tests PASSED\n" );

    // CI: this message is being watched by CI scripts (ci-runtest.sh)
    printf( "-----\nPhantom test suite FINISHED\n-----\n" );

}
static void phantom_debug_window_loop()
{
    static char buf[DEBBS+1];
    int step = 0;

    int show = 's';

    t_current_set_name("Debug Win");
    // Which thread will receive typein for this window
    phantom_debug_window->owner = get_current_tid();

    int wx = 600;

#if CONF_NEW_CTTY
	if( t_new_ctty( get_current_tid() ) )
		panic("console t_new_ctty");
#else
    // Need separate ctty
    t_set_ctty( get_current_tid(), wtty_init( WTTY_SMALL_BUF ) );
#endif
    // TODO HACK! Need ioctl to check num of bytes?
    wtty_t *tty;
    t_get_ctty( get_current_tid(), &tty );


    while(1)
    {
        if(tty && !wtty_is_empty(tty))
        {
            char c = wtty_getc( tty );
            switch(c)
            {
            case '?':
            case'h':
                printf(
                       "Commands:\n"
                       "---------\n"
                       "w\t- show windows list\n"
                       "t\t- show threads list\n"
                       "s\t- show stats\n"
                       "p\t- show profiler\n"
                       "d\t- dump threads to JSON\n"
                      );
                break;
            case 'p': // profiler
            case 't':
                //w_set_title( phantom_debug_window,  "Threads" );
                //show = c;
                //break;

            case 'w':
                //w_set_title( phantom_debug_window,  "Windows" );
                //show = c;
                //break;

            case 's':
                //w_set_title( phantom_debug_window,  "Stats" );
                show = c;
                break;

            case 'd':
                {
                    json_output jo = { 0 };

                    json_start( &jo );
                    json_dump_threads( &jo );
                    json_stop( &jo );

                }
                break;
            }
        }


        {
            static char old_show = 0;
            if( old_show != show )
            {
                old_show = show;
                switch(show)
                {
                case 't':
                    w_set_title( phantom_debug_window,  "Threads" );
                    break;

                case 'w':
                    w_set_title( phantom_debug_window,  "Windows" );
                    break;

                case 's':
                    w_set_title( phantom_debug_window,  "Stats" );
                    break;

                case 'p':
                    w_set_title( phantom_debug_window,  "Profiler" );
                    break;
                }
            }
        }


        //hal_sleep_msec(1000);
        hal_sleep_msec(100);
#if 1
#if 1
        w_clear( phantom_debug_window );
        ttyd = DEBWIN_YS-20;
        ttxd = 0;
#endif
        //put_progress();

        void *bp = buf;
        int len = DEBBS;
        int rc;

        time_t sec = uptime();
        int min = sec/60; sec %= 60;
        int hr = min/60; min %= 60;
        int days = hr/24; hr %= 24;

        struct tm mt = *current_time;

        rc = snprintf(bp, len, " View: \x1b[32mt\x1b[37mhreads \x1b[32ms\x1b[37mtats \x1b[32mw\x1b[37mindows \x1b[32mp\x1b[37mrofile       \x1b[32m?\x1b[37m - help\n \x1b[32mStep %d, uptime %dd, %02d:%02d:%02d\x1b[37m, %d events\n Time %04d/%02d/%02d %02d:%02d:%02d GMT, CPU 0 %2d%% idle\n",
                      step++, days, hr, min, (int)sec,
                      ev_get_n_events_in_q(),
                      mt.tm_year + 1900, mt.tm_mon, mt.tm_mday,
                      mt.tm_hour, mt.tm_min, mt.tm_sec, 100-percpu_cpu_load[0]
                     );
        bp += rc;
        len -= rc;

        switch(show)
        {
        case 't':
        default:
            phantom_dump_threads_buf(bp,len);
            break;

        case 'w':
            phantom_dump_windows_buf(bp,len);
            break;

        case 's':
            phantom_dump_stats_buf(bp,len);
            break;

        case 'p':
            phantom_dump_profiler_buf(bp,len);
            break;
        }

        phantom_debug_window_puts(buf);

        if(wx == 600) wx = 620; else wx = 600;
        //w_move( phantom_debug_window, wx, 50 );
#endif
        put_progress();
        w_update( phantom_debug_window );

    }
}
Exemple #26
0
static void do_syscall_sw( uuprocess_t *u, struct trap_state *st)
{
#if HAVE_UNIX
    int callno = st->eax;

    /*
    unsigned int mina = 0, maxa = 0;
    {
        extern struct real_descriptor 	ldt[];

        struct real_descriptor  dsd = ldt[ st->ds/8 ];
        mina = dsd.base_low | (dsd.base_med << 16) | (dsd.base_high << 24);
        maxa = (dsd.limit_low | dsd.limit_high << 16);
        if( dsd.granularity & SZ_G)
            maxa *= PAGE_SIZE;
        maxa += mina;
        }
    */


    //phantom_thread_t *t = GET_CURRENT_THREAD();
    //uuprocess_t *u = t->u;

    /*
    tid_t tid = get_current_tid();
    pid_t pid;
    assert( !t_get_pid( tid, &pid ));
    uuprocess_t *u = proc_by_pid(pid);
    */

    assert( u != 0 );

    unsigned int mina = (int)u->mem_start, maxa = (int)u->mem_end;

    // trap state is good for interrupt.
    // call gate does not push eflags
    int user_esp = st->eflags;

#ifndef ARCH_ia32
#  warning machdep ia32 arg pass convention
#endif
    // list of user syscsall arguments
    int *uarg = adjustin( user_esp, st );
    uarg++; // syscall func return addr

    //SHOW_FLOW( 10, "Syscall pid %2d tid %2d, our esp %p, user esp %p, t kstack %p", u->pid, t->tid, &st, user_esp, t->kstack_top );
    SHOW_FLOW( 8, "Syscall %d args %x, %x, %x", callno, uarg[0], uarg[1],uarg[2] );

    int ret = 0;
    int err = 0;


    switch(callno)
    {
    case SYS__exit:
        // TODO housekeeping?
        SHOW_FLOW( 2, "exit %d", uarg[0] );
        hal_exit_kernel_thread();
        err = ENOSYS;
        break;

    case SYS_ssyslog:
        syslog( uarg[0], "%s", (const char *)adjustin( uarg[1], st ) );
        SHOW_FLOW( 2, "syslog %d %s", uarg[0], (const char *)adjustin( uarg[1], st ) );
        //SHOW_ERROR0( 0, "syslog not impl" );
        break;





    case SYS_sleepmsec:
        //SHOW_FLOW( 2, "sleepmsec %d", uarg[0] );
        hal_sleep_msec(uarg[0]);
        break;



    case SYS_getpagesize:       ret = PAGE_SIZE; break;

    case SYS_personality:
        if( ((unsigned) uarg[0]) == 0xffffffff)
        {
            ret = 0; // Say we're Linux... well...to some extent.
            break;
        }
        err = EINVAL;
        break;

    case SYS_uname:
        err = copyout(uarg[0], mina, maxa, &phantom_uname, sizeof(phantom_uname) );
        if( err ) ret = -1;
        break;


    case SYS_getuid:            ret = u->uid; break;
    case SYS_getuid32:          ret = u->uid;; break;
    case SYS_getegid:           ret = u->egid; break;
    case SYS_getegid32:         ret = u->egid; break;
    case SYS_geteuid:           ret = u->euid; break;
    case SYS_geteuid32:         ret = u->euid; break;
    case SYS_getgid:            ret = u->gid; break;
    case SYS_getgid32:          ret = u->gid; break;

    case SYS_gettid:            ret = get_current_tid(); break;
    case SYS_getpid:            ret = u->pid; break;
    case SYS_getpgrp:           ret = u->pgrp_pid; break;
    case SYS_getppid:           ret = u->ppid; break;

    case SYS_getpgid:
        goto unimpl;

    case SYS_time:
        {
            time_t t = time(0);

            AARG(time_t *, tp, 0, sizeof(time_t));

            *tp = t;
            ret = t;
            break;
        }
    case SYS_nanosleep:
        // todo check for POSIX compliance, make it interruptible by signals
        //int nanosleep(const struct timespec *, struct timespec *);
        {
            goto unimpl;
            //AARG(struct timespec *,  req_time, 0, sizeof(struct timespec));
            //AARG(struct timespec *, rest_time, 1, sizeof(struct timespec));
            //ret = usys_nanosleep( &err, u, req_time, rest_time );
            //break;
        }


    case SYS_sync:
    case SYS_sysinfo:
    case SYS_sysfs:
    case SYS_klogctl:

    case SYS_shutdown:
    case SYS_reboot:



    case SYS_getitimer:
    case SYS_setitimer:
    case SYS_gettimeofday:


    case SYS_setuid:
    case SYS_setuid32:          CHECK_CAP(CAP_SETUID); u->euid = uarg[0]; break;

    case SYS_setgid:            
    case SYS_setgid32:          CHECK_CAP(CAP_SETGID); u->egid = uarg[0]; break;

    case SYS_setgroups:
    case SYS_setgroups32:
        goto unimpl;

    case SYS_setpgid:
    case SYS_setregid:
    case SYS_setregid32:
    case SYS_setresgid:
    case SYS_setresgid32:
    case SYS_setresuid:
    case SYS_setresuid32:
    case SYS_setreuid:
    case SYS_setreuid32:
        goto unimpl;

    case SYS_open:              ret = usys_open(&err, u, adjustin( uarg[0], st ), uarg[1], uarg[2] ); break;
    case SYS_close:             ret = usys_close(&err, u, uarg[0] ); break;
    case SYS_read:
        {
            int count = uarg[2];
            void *addr = adjustin( uarg[1], st );
            CHECKA(addr,count);
            ret = usys_read(&err, u, uarg[0], addr, count );
            break;
        }
    case SYS_write:
        {
            int count = uarg[2];
            void *addr = adjustin( uarg[1], st );
            CHECKA(addr,count);
            ret = usys_write(&err, u, uarg[0], addr, count );
            break;
        }
    case SYS_lseek: ret = usys_lseek(&err, u, uarg[0], uarg[1], uarg[2] ); break;
    case SYS_creat: ret = usys_creat(&err, u, adjustin( uarg[0], st ), uarg[1] ); break;
    case SYS_chdir:
        {
            AARG(const char *, path, 0, 0);
            ret = usys_chdir(&err, u, path );
            break;
        }

    case SYS_pipe:
        {
            AARG(int *, fds, 0, sizeof(int) * 2);
            ret = usys_pipe( &err, u, fds );
            break;
        }

    case SYS_rmdir:
    case SYS_unlink:
        {
            AARG(const char *, name, 0, 1);
            ret = usys_rm( &err, u, name );
            break;
        }


    case SYS_dup:
        ret = usys_dup( &err, u, uarg[0] );
        break;

    case SYS_dup2:
        ret = usys_dup2( &err, u, uarg[0], uarg[1] );
        break;

    case SYS_symlink:
        {
            AARG(const char *, n1, 0, 1);
            AARG(const char *, n2, 1, 1);
            ret = usys_symlink( &err, u, n1, n2 );
            break;
        }

    case SYS_getcwd:
        {
            AARG(char *, buf, 0, uarg[1]);
            ret = usys_getcwd( &err, u, buf, uarg[1] );
            break;
        }

    case SYS_mkdir:
        {
            AARG(const char *, path, 0, 2);
            ret = usys_mkdir( &err, u, path );
            break;
        }

    case SYS_link:
    case SYS__llseek:
    case SYS_chroot:
    case SYS_lstat64:
    case SYS_mknod:
        goto unimpl;

    case SYS_mount:
        {
            const char *source = adjustin( uarg[0], st );
            CHECKA(source,0);
            const char *target = adjustin( uarg[1], st );
            CHECKA(target,0);
            const char *fstype = adjustin( uarg[2], st );
            CHECKA(target,0);
            const void *data = adjustin( uarg[4], st );
            CHECKA(data,0);

            ret = usys_mount(&err, u, source, target, fstype, uarg[3], data );
            break;
        }
    case SYS_umount:
        {
            const char *target = adjustin( uarg[0], st );
            CHECKA(target,0);
            ret = usys_umount(&err, u, target, 0 );
            break;
        }

    /*
    case SYS_umount2:
        {
            const char *target = adjustin( uarg[0], st );
            CHECKA(target);
            ret = usys_umount(&err, u, target, uarg[1] );
            break;
        }
    */

    case SYS_truncate:
        {
            AARG(const char *, path, 0, 0);
            ret = usys_truncate(&err, u, path, uarg[1] );
            break;
        }
    case SYS_ftruncate:
        {
            ret = usys_ftruncate(&err, u, uarg[0], uarg[1] );
            break;
        }

    case SYS_truncate64:
    case SYS_ftruncate64:
        goto unimpl;

    case SYS_fchdir:
        ret = usys_fchdir( &err, u, uarg[0] );
        break;

    case SYS_readdir:
        {
            AARG(struct dirent *, ent, 1, sizeof(struct dirent));
            ret = usys_readdir( &err, u, uarg[0], ent );
            break;
        }
    case SYS_fchmod:
        ret = usys_fchmod( &err, u, uarg[0], uarg[1] );
        break;

    case SYS_fchown:
    case SYS_fchown32:
        ret = usys_fchown( &err, u, uarg[0], uarg[1], uarg[2] );
        break;

    case SYS_fcntl:
        {
            //AARG(void *, str, 2, sizeof(int)); // FIXME size of arg?
            ret = usys_fcntl( &err, u, uarg[0], uarg[1], uarg[0] );
        }
        break;

    case SYS_fcntl64:
    case SYS_fdatasync:
    case SYS_flock:

    case SYS_fstat64:
    case SYS_fstatfs:
    case SYS_fsync:

    case SYS_utime:
    case SYS_chmod:
    case SYS_chown:
    case SYS_chown32:
    case SYS_access:
    case SYS_lchown:
    case SYS_lchown32:
    case SYS_pread:
    case SYS_pwrite:
        goto unimpl;

    case SYS_readv:
        {
            int fd = uarg[0];
            int iovcnt = uarg[2];
            AARG(struct iovec *, list, 1, sizeof(struct iovec) * iovcnt);

            unsigned int onerc;
            int lp;

            for( lp = 0; lp < iovcnt; lp++ )
            {
                void *addr = adjustin( list[lp].iov_base, st );
                CHECKA(addr,list[lp].iov_len);
                onerc = usys_read(&err, u, fd, addr, list[lp].iov_len );

                /*
                if( onerc < 0 )
                {
                    ret = -1;
                    goto err_ret;
                }
                */
                ret += onerc;
                if( onerc < list[lp].iov_len )
                    break;
            }
            break;
        }

    case SYS_writev:
        {
            int fd = uarg[0];
            int iovcnt = uarg[2];
            AARG(struct iovec *, list, 1, sizeof(struct iovec) * iovcnt);

            unsigned int onerc;
            int lp;

            for( lp = 0; lp < iovcnt; lp++ )
            {
                void *addr = adjustin( list[lp].iov_base, st );
                CHECKA(addr,list[lp].iov_len);
                onerc = usys_write(&err, u, fd, addr, list[lp].iov_len );

                /*
                if( onerc < 0 )
                {
                    ret = -1;
                    goto err_ret;
                }
                */
                ret += onerc;
                if( onerc < list[lp].iov_len )
                    break;
            }
            break;
        }

    case SYS_readlink:
        goto unimpl;


    case SYS_gethostname:
        {
            int len = uarg[1];
            char *target = adjustin( uarg[0], st );
            CHECKA(target,len);
            ret = usys_gethostname(&err, u, target, len );
            break;
        }
    case SYS_sethostname:
        {
            int len = uarg[1];
            const char *target = adjustin( uarg[0], st );
            CHECKA(target,len);
            ret = usys_sethostname(&err, u, target, len );
            break;
        }



    case SYS_socket:
        ret = usys_socket( &err, u, uarg[0], uarg[1], uarg[2] );
        break;

    case SYS_setsockopt:
        {
            socklen_t optlen = uarg[4];
            AARG(const void *, optval, 3, optlen);
            ret = usys_setsockopt( &err, u, uarg[0], uarg[1], uarg[2], optval, optlen);
            break;
        }
    case SYS_getsockopt:
        {
            AARG(socklen_t *, optlen, 4, sizeof(socklen_t));
            AARG(void *, optval, 3, *optlen);
            ret = usys_getsockopt( &err, u, uarg[0], uarg[1], uarg[2], optval, optlen);
            break;
        }

    case SYS_getpeername:
        {
            AARG(socklen_t *, namelen, 2, sizeof(socklen_t));
            AARG(struct sockaddr *, name, 1, *namelen);
            ret = usys_getpeername( &err, u, uarg[0], name, namelen);
            break;
        }
    case SYS_getsockname:
        {
            AARG(socklen_t *, namelen, 2, sizeof(socklen_t));
            AARG(struct sockaddr *, name, 1, *namelen);
            ret = usys_getsockname( &err, u, uarg[0], name, namelen);
            break;
        }

    case SYS_bind:
        {
            AARG(const struct sockaddr *, addr, 1, sizeof(struct sockaddr));
            ret = usys_bind( &err, u, uarg[0], addr, uarg[2] );
            break;
        }

    case SYS_listen:
        ret = usys_listen( &err, u, uarg[0], uarg[1] );
        break;

    case SYS_accept:
        {
            AARG( socklen_t *, len, 2, sizeof(socklen_t));
            AARG( struct sockaddr *, acc_addr, 1, *len );
            ret = usys_accept( &err, u, uarg[0], acc_addr, len );
            break;
        }

    case SYS_recv:
        {
            int len = uarg[2];
            AARG( void *, buf, 0, len );
            ret =  usys_recv( &err, u, uarg[0], buf, len, uarg[3] );
            break;
        }

    case SYS_recvmsg:
        {
            AARG( struct msghdr *, msg, 0, sizeof(struct msghdr) );
            ret = usys_recvmsg( &err, u, uarg[0], msg, uarg[2] );
            break;
        }

    case SYS_send:
        {
            int len = uarg[2];
            AARG( const void *, buf, 0, len );
            ret =  usys_send( &err, u, uarg[0], buf, len, uarg[3] );
            break;
        }

    case SYS_sendmsg:
        {
            AARG( const struct msghdr *, msg, 0, sizeof(struct msghdr) );
            ret = usys_sendmsg( &err, u, uarg[0], msg, uarg[2] );
            break;
        }

    case SYS_sendto:
        {
            socklen_t tolen = uarg[5];
            AARG( const struct sockaddr *, to, 4, tolen );
            int len = uarg[2];
            AARG( const void *, buf, 0, len );
            ret =  usys_sendto( &err, u, uarg[0], buf, len, uarg[3], to, tolen );
            break;
        }

    case SYS_recvfrom:
        {
            AARG( socklen_t *, fromlen, 5, sizeof(socklen_t) );
            AARG( struct sockaddr *, from, 4, *fromlen );
            int len = uarg[2];
            AARG( void *, buf, 0, len );
            ret =  usys_recvfrom( &err, u, uarg[0], buf, len, uarg[3], from, fromlen );
            break;
        }



    case SYS_connect:
        // int connect(int socket, const struct sockaddr *address, socklen_t address_len);
        {
            int len = uarg[2];
            AARG( struct sockaddr *, acc_addr, 1, len );
            ret = usys_connect( &err, u, uarg[0], acc_addr, len );
            break;
        }

    case SYS_socketpair:
        {
            AARG( int *, sv, 3, sizeof(int) * 2 );
            ret = usys_socketpair( &err, u, uarg[0], uarg[1], uarg[2], sv );
            break;
        }




    case SYS_sendfile:
    case SYS_socketcall:
        goto unimpl;

    case SYS_nice:
        {
            // int nice = uarg[0];
            // set thr prio
            // break;
            goto unimpl;
        }

    case SYS_brk:
        goto unimpl;
        /*{
            ret = usys_sbrk( &err, u, uarg[0] );
            break;
        }*/

    case SYS_fork:
    case SYS_vfork:
        goto unimpl;

    case SYS_ioctl:
        {
            void *data = adjustin( uarg[2], st );
            CHECKA(data,0);
            ret = usys_ioctl( &err, u, uarg[0], uarg[1], data, uarg[3] );
            break;
        }

        int statlink;
    case SYS_lstat: statlink = 1; goto dostat;
    case SYS_stat: statlink = 0; goto dostat;

    dostat:
        {
            const char *path = adjustin( uarg[0], st );
            CHECKA(path,0);
            struct stat *data = adjustin( uarg[1], st );
            CHECKA(data,sizeof(struct stat));
            ret = usys_stat( &err, u, path, data, statlink );
            break;
        }

    case SYS_fstat:
        {
            struct stat *data = adjustin( uarg[1], st );
            CHECKA(data,sizeof(struct stat));
            ret = usys_fstat( &err, u, uarg[0], data, 0 );
            break;
        }

    case SYS_umask:
        {
            ret = u->umask;
            u->umask = uarg[0];
            break;
        }

    case SYS_kill:
        {
            ret = usys_kill( &err, u, uarg[0], uarg[1] );
            break;
        }

    case SYS_waitpid:
        {
            AARG(int *, addr, 1, sizeof(int));
            ret = usys_waitpid( &err, u, uarg[0], addr, uarg[2] );
            break;
        }

    case SYS_wait:
        {
            AARG(int *, addr, 0, sizeof(int));
            ret = usys_waitpid( &err, u, -1, addr, 0 );
            break;
        }


    case SYS_clone:
        goto unimpl;


    case SYS_madvise:
    case SYS_mincore:
    case SYS_mlock:
    case SYS_mlockall:
    case SYS_mmap:
    case SYS_mprotect:
    case SYS_mremap:
    case SYS_msync:
    case SYS_munlock:
    case SYS_munlockall:
    case SYS_munmap:
        goto unimpl;


        // NewOS/BeOS/Haiku
    case SYS_create_port:
        {
            // TODO check string length and final addr to be valid
            AARG(const char *, name, 1, 0);
            ret = port_create( uarg[0], name );
            break;
        }
    case SYS_close_port:
        ret = port_close( uarg[0] );
        break;
    case SYS_delete_port:
        ret = port_delete( uarg[0] );
        break;
    case SYS_find_port:
        {
            // TODO check string length and final addr to be valid
            AARG(const char *, name, 0, 0);
            ret = port_find(name);
            break;
        }
    case SYS_get_port_info:
        {
            AARG(struct port_info *, info, 1, sizeof(struct port_info));
            ret = port_get_info( uarg[0], info);
        }
    case SYS_get_port_bufsize:
        ret = port_buffer_size( uarg[0] );
        break;
    case SYS_get_port_bufsize_etc:
        ret = port_buffer_size_etc( uarg[0], uarg[1], uarg[2] );
        break;
    case SYS_get_port_count:
        ret = port_count( uarg[0] );
        break;
    case SYS_read_port:
        {
            AARG(int32_t *, msg_code, 1, sizeof(int32_t));
            AARG(void  *, msg_buffer, 2, uarg[3]);
            ret = port_read( uarg[0],
                             msg_code,
                             msg_buffer,
                             uarg[3]);
            break;
        }
    case SYS_write_port:
        {
            //AARG(int32_t *, msg_code, 1, sizeof(int32_t));
            //AARG(int32_t, msg_code, 1, sizeof(int32_t));
            AARG(void  *, msg_buffer, 2, uarg[3]);
            ret = port_write( uarg[0],
                             uarg[1],
                             msg_buffer,
                             uarg[3]);
            break;
        }
    case SYS_read_port_etc:
    case SYS_write_port_etc:
    case SYS_set_port_owner:
    case SYS_get_next_port_info:
        goto unimpl;

    case SYS_phantom_run:
        {
            // extern int phantom_run(const char *fname, const char **argv, const char **envp, int flags);
            AARG(const char  *, fname, 0, 1);

            AARG(const char **, uav,   1, 4);
            AARG(const char **, uep,   2, 4);

            if( 0 == uarg[1] ) uav = 0;
            if( 0 == uarg[2] ) uep = 0;

            SHOW_FLOW( 2, "run %s flags 0x%b", fname, uarg[3], "\020\1<WAIT>\2<NEWWIN>\3<NEWPGRP>" );

            char *a[1024];
            char *e[1024];

            SHOW_FLOW( 2, "run %s load args", fname );

            if(
               user_args_load( mina, maxa, a, 1024, uav ) ||
               user_args_load( mina, maxa, e, 1024, uep )
              )
            {
                ret = -1;
                err = EFAULT;
                SHOW_ERROR( 0, "fault reading args for %s", fname );
                goto err_ret;
            }

            ret = usys_run( &err, u, fname, (const char**)a, (const char**)e, uarg[3] );
            break;
        }

    case SYS_phantom_method:
        // AARG(const char *, m_name, 0, 1);
        // int nfd = aarg[1];
        // AARG(int *, fds, 0, sizeof(int)*nfd);

        // ret = usys_pmethod( &err, u, m_name, int nfd, int fds[] );

    case SYS_phantom_toobject:
    case SYS_phantom_fromobject:
    case SYS_phantom_intmethod:
    case SYS_phantom_strmethod:
        goto unimpl;

        // extern int phantom_runclass(const char *cname, int nmethod, int flags);
    case SYS_phantom_runclass:
        {
            AARG(const char  *, cname, 0, 1);
            unsigned flags = uarg[2];

            if(flags)
                SHOW_ERROR( 0, "SYS_phantom_runclass: unknown flags %x" , flags );

            usys_phantom_runclass( &err, u, cname, uarg[1] );
            ret = err;
        }
        break;

    case SYS_setproperty:
        {
            AARG(const char *, pName, 1, 1); // TODO check zero term string!
            AARG(const char *, pValue, 2, 1);

            usys_setproperty( &err, u, uarg[0], pName, pValue );
            ret = err;
        }
        break;

    case SYS_getproperty:
        {
            AARG(const char *, pName, 1, 1); // TODO check zero term string!
            AARG(char *, pValue, 2, uarg[3]);

            usys_getproperty( &err, u, uarg[0], pName, pValue, uarg[3] );
            ret = err;
        }
        break;

    case SYS_listproperties:
        {
            AARG(char *, buf, 2, uarg[3]);
            usys_listproperties( &err, u, uarg[0], uarg[1], buf, uarg[3] );
            ret = err;
        }
        break;


    case SYS_name2ip:
        {
            AARG(in_addr_t *, out, 0, sizeof(in_addr_t));
            AARG(const char *, name, 1, 1);

            ret = name2ip( out, name, uarg[2] );
            if( ret != 0 ) err = ret;
        }
        break;


    case SYS_sigpending:
        {
            AARG(sigset_t *, set, 0, sizeof(sigset_t *));
            ret = usys_sigpending( &err, u, set);
            break;
        }

    case SYS_signal:
        {
#if 0
            AARG(sighandler_t, hand, 1, sizeof(sighandler_t));
            hand = usys_signal( &err, u, uarg[0], hand);
            // FIXME 64 bit error
            ret = ((int)hand) - mina; // Convert pointer back
#else
            // We do not use pointer (ret and uarg 1), so we don't have to convert it
            ret = (int)usys_signal( &err, u, uarg[0], (void *)uarg[1]);
#endif
            break;
        }

    case SYS_sigprocmask:
    //case raise:
    case SYS_sigaction:
    case SYS_siginterrupt:
    case SYS_sigsuspend:
        goto unimpl;


    unimpl:
        SHOW_ERROR( 0, "Unimplemented syscall %d called", callno );
        err = ENOSYS;
        break;

    default:
        SHOW_ERROR( 0, "Unknown syscall %d called", callno );
        err = ENOSYS;
        break;
    }

#else // HAVE_UNIX
    int err = ENOSYS;
    int ret = -1;
    goto err_ret; // to clear warning
#endif // HAVE_UNIX

err_ret:

#ifdef ARCH_ia32
#define _RET_OK
    st->eax = ret;
    st->edx = err;
#endif

#ifdef ARCH_mips
#define _RET_OK
    st->r2 = ret; // v0 (normal ret register, low)
    st->r3 = err; // v1 (normal ret register, hi)
#endif

#ifdef ARCH_arm
#define _RET_OK
    st->r0 = ret; // normal ret register
    st->r1 = err; // arg1 reg, we can safely use for return of errno
#endif

#ifndef _RET_OK
#error arch ret
#endif

}
/*!
 * \brief Fetch the next packet out of the receive ring buffer.
 *
 * Nic interrupts must be disabled when calling this funtion.
 *
 */
static int NicGetPacket( struct phantom_device *dev, void *buf, int len )
{
    //NETBUF *nb = 0;
    //uint8_t *buf;
    u_int16_t f_status_word;
    u_int16_t fbytecount;

    /* Check the fifo empty bit. If it is set, then there is 
       nothing in the receiver fifo. */
    nic_bs(2);
    //if (nic_inw(NIC_FIFO) & 0x8000)
    //    return 0;

    // TODO cond/sem timed wait
    while(nic_inw(NIC_FIFO) & 0x8000)
        hal_sleep_msec(100);

    /* Inialize pointer register. */
    nic_outw(NIC_PTR, PTR_READ | PTR_RCV | PTR_AUTO_INCR);
    _NOP();
    _NOP();
    _NOP();
    _NOP();

    /* Read status word and byte count. */
    f_status_word = nic_inw(NIC_DATA);
    fbytecount = nic_inw(NIC_DATA);
    //printf("[SW=%04X,BC=%04X]", f_status_word, fbytecount);


    int ret = ERR_IO_ERROR;

    /* Check for frame errors. */
    if (f_status_word & 0xAC00) {
        //nb = (NETBUF *) 0xFFFF;
        ret = ERR_IO_ERROR;
    }
    /* Check the byte count. */
    else if (fbytecount < 66 || fbytecount > 1524) {
        //nb = (NETBUF *) 0xFFFF;
        ret = ERR_IO_ERROR;
    }
    else {
        /* 
         * Allocate a NETBUF. 
         * Hack alert: Rev A chips never set the odd frame indicator.
         */
        fbytecount -= 3;

        if( len < fbytecount )
            ret = ERR_VFS_INSUFFICIENT_BUF;
        else
        {
            NicRead( dev, buf, fbytecount);
            ret = fbytecount;
        }
    }

    /* Release the packet. */
    nic_outlb(NIC_MMUCR, MMU_TOP);

    return ret;
}
phantom_device_t * driver_lanc111_probe( int port, int irq, int stage )
{
    (void) stage;



    lanc111_nic_t *nic = NULL;

    SHOW_INFO0( 0, "probe");
    nic = calloc( 1, sizeof(lanc111_nic_t) );

    assert(nic != NULL);



    hal_sleep_msec(10);

    if(LancInit(nic) < 0)
    {
        SHOW_ERROR0( 0, "init failed");
        goto free1;
    }

    // Disable NIC interrupt.
    //cbi(EIMSK, LANC111_SIGNAL_IRQ);



    phantom_device_t * dev = calloc(1, sizeof(phantom_device_t));
    dev->name = "lanc111";
    dev->seq_number = seq_number++;
    dev->drv_private = nic;

    //NutEtherInput,              /*!< \brief Routine to pass received data to, if_recv(). */
    //LancOutput,                 /*!< \brief Driver output routine, if_send(). */
    //NutEtherOutput              /*!< \brief Media output routine, if_output(). */

    //dev->dops.read = pcnet32_read;
    //dev->dops.write = pcnet32_write;
    //dev->dops.get_address = pcnet32_get_address;

    dev->iobase = port;
    dev->irq = irq;
    //dev->iomem = ;
    //dev->iomemsize = ;


    if( hal_irq_alloc( irq, &NicInterrupt, dev, HAL_IRQ_SHAREABLE ) )
    {
        SHOW_ERROR( 0, "IRQ %d is busy", irq );
        goto free2;
    }

    static CONST uint8_t mac[6] = { 0x52, 0x54, 0x00, 0x12, 0x34, 0x86 }; // QEMU's range

    if( NicStart(dev, mac) ) goto free2;

    /*
     * Start the receiver thread.
     *
     */
    //NutThreadCreate("rxi5", NicRxLanc, dev, (NUT_THREAD_LANCRXSTACK * NUT_THREAD_STACK_MULT) + NUT_THREAD_STACK_ADD);

    ifnet *interface;
    if( if_register_interface( IF_TYPE_ETHERNET, &interface, dev) )
    {
        SHOW_ERROR( 0, "Failed to register interface for %s", dev->name );
    }
    else
    {
        if_simple_setup(interface, WIRED_ADDRESS, WIRED_NETMASK, WIRED_BROADCAST, WIRED_NET, WIRED_ROUTER, DEF_ROUTE_ROUTER );
    }


    return dev;

free2:
    free( dev );
free1:
    free( nic );

    return 0;
}
Exemple #29
0
int do_test_dpc(const char *test_parm)
{
    (void) test_parm;

    int rc = 0;

    dpc_request_init( &dpc1, dpc_serve1 );
    dpc_request_init( &dpc2, dpc_serve2 );

    // DPC engine runs next thread only after a second
    hal_sleep_msec(2000);


    dpc_request_trigger( &dpc1, DPC_ARG1 );
    hal_sleep_msec(200);
    dpc_request_trigger( &dpc2, DPC_ARG2 );
    hal_sleep_msec(200);

    if( !dpc1_triggered )
    {
        rc = -1;
        SHOW_ERROR0( 0, "DPC 1 lost" );
    }

    if( !dpc2_triggered )
    {
        rc = -1;
        SHOW_ERROR0( 0, "DPC 2 lost" );
    }

    dpc1_triggered = 0;
    dpc2_triggered = 0;

    hal_sleep_msec(200);

    if( dpc1_triggered )
    {
        rc = -1;
        SHOW_ERROR0( 0, "DPC 1 sporadic" );
    }

    if( dpc2_triggered )
    {
        rc = -1;
        SHOW_ERROR0( 0, "DPC 2 sporadic" );
    }

    dpc_request_trigger( &dpc2, DPC_ARG2 );

    hal_sleep_msec(200);

    if( dpc1_triggered )
    {
        rc = -1;
        SHOW_ERROR0( 0, "DPC 1 sporadic after DPC 2 trigger" );
    }

    if( !dpc2_triggered )
    {
        rc = -1;
        SHOW_ERROR0( 0, "DPC 2 lost 2" );
    }

    return rc;
}
Exemple #30
0
int do_test_timed_call(const char *test_parm)
{
    (void) test_parm;


    printf("Testing timed call undo, must be no echoes:\n");
    called = 0;

    phantom_request_timed_call( &t2, 0 );
    phantom_undo_timed_call(&t2);

    hal_sleep_msec(200); // Twice the time
    test_check_eq(called, 0);


#if DUMPQ
    //dump_timed_call_queue();
#endif


    called = 0;

    printf("Testing timed calls, wait for echoes:\n");

    phantom_request_timed_call( &t1, 0 );
    //test_check_false(called); // it is still possible for this test to fail with correct code!
    phantom_request_timed_call( &t2, 0 );
#if DUMPQ
    //dump_timed_call_queue();
#endif
    phantom_request_timed_call( &t3, 0 );
    phantom_request_timed_call( &t4, 0 );

    //TIMEDCALL_FLAG_AUTOFREE requires call to free from interrupt :(
    //phantom_request_timed_func( echo, msg, 5000, 0 );
    phantom_request_timed_call( &t5, 0 );

#if DUMPQ
    dump_timed_call_queue();
#endif

    // We check for >= (ge) because hal_sleep... can cleep for more than asked, and timed
    // calls are usually quite on time

    hal_sleep_msec(6);
    test_check_ge(called, 1);

    hal_sleep_msec(200); // Have lag of 106 msec, OK?
    test_check_ge(called, 2);

    hal_sleep_msec(2000-100); // Still have lag of 106 msec
    test_check_ge(called, 3);

    hal_sleep_msec(5000-2000); // Have lag of 206 msec
    test_check_ge(called, 4);

    hal_sleep_msec(2500+10000-5000-2000); // Strange - need quite big lag here...
    test_check_ge(called, 5);



    printf("Done testing timed calls\n");
    return 0;
}