phantom_device_t * driver_isa_com_probe( int port, int irq, int stage )
{
    (void) stage;
    if( !com_detect( seq_number, port) )
        return 0;


    phantom_device_t * dev = calloc(sizeof(phantom_device_t), 1);

    dev->iobase = port;
    dev->irq = irq;

    dev->name = "com";
    dev->seq_number = seq_number++;


    dev->dops.start = com_start;
    dev->dops.stop = com_stop;

    dev->dops.read = com_read;
    dev->dops.write = com_write;

    if( hal_irq_alloc( irq, &com_interrupt, dev, HAL_IRQ_SHAREABLE ) )
    {
        SHOW_ERROR( 0, "IRQ %d is busy", irq );
        free(dev);
        return 0;
    }


    com_port_t *cp = calloc( sizeof(com_port_t), 1 );
    dev->drv_private = cp;

    hal_sem_init( &(cp->rsem), "serialRd" );
    hal_sem_init( &(cp->wsem), "serialWr" );

    cp->rdq = wtty_init(); assert(cp->rdq);
    cp->wrq = wtty_init(); assert(cp->wrq);


    cp->baudRate = 9600;
    cp->stopBits = 1;
    cp->dataBits = 8;
    cp->parity = 0;

    com_setbaud(dev, cp->baudRate);

    hal_start_kernel_thread_arg( com_rd_thread, dev );
    hal_start_kernel_thread_arg( com_wr_thread, dev );

    return dev;
}
Esempio n. 2
0
phantom_device_t * driver_isa_ps2m_probe( int port, int irq, int stage )
{
    (void) port;
    (void) stage;

    //dpc_request_init( &mouse_dpc, push_event );
    //hal_mutex_init( &mouse_mutex, "MouseDrv" );
    //hal_cond_init( &mouse_cond );
    hal_sem_init( &mouse_sem, "MouseDrv" );
    hal_spin_init( &elock );

    if( seq_number || ps2ms_do_init() )
        return 0;

    if( hal_irq_alloc( irq, ps2ms_int_handler, 0, HAL_IRQ_SHAREABLE ) )
        return 0;

    phantom_device_t * dev = malloc(sizeof(phantom_device_t));
    dev->name = "ps2-mouse";
    dev->seq_number = seq_number++;

    hal_start_kernel_thread((void*)mouse_push_event_thread);

    return dev;
}
Esempio n. 3
0
int net_timer_init(void)
{
    int err;

    net_q.next = net_q.prev = (net_timer_event *)&net_q;

    err = hal_mutex_init(&net_q.lock, "net timer mutex");
    if(err < 0)
        return err;

    //net_q.wait_sem = sem_create(0, "net timer wait sem");

    if( hal_sem_init(&(net_q.wait_sem), "NetQ") < 0 ) {
        mutex_destroy(&net_q.lock);
        return -1; //net_q.wait_sem;
    }


    //net_q.runner_thread = thread_create_kernel_thread("net timer runner", &net_timer_runner, NULL);
    net_q.runner_thread = hal_start_kernel_thread_arg( &net_timer_runner, NULL );

    if(net_q.runner_thread < 0) {
        sem_delete(net_q.wait_sem);
        mutex_destroy(&net_q.lock);
        return -1; //net_q.runner_thread;
    }
    //thread_resume_thread(net_q.runner_thread);


    return 0;
}
Esempio n. 4
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;
}
Esempio n. 5
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;

}
Esempio n. 6
0
int udp_open(void **prot_data)
{
    udp_endpoint *e = calloc( sizeof(udp_endpoint), 1 );
    if(!e)
        return ERR_NO_MEMORY;

    hal_mutex_init(&e->lock, "UDP endp");
    //e->blocking_sem = sem_create(0, "udp endpoint sem");
    hal_sem_init(&(e->blocking_sem), "UDP blk");
    e->port = 0;
    e->ref_count = 1;
    udp_init_queue(&e->q);

    mutex_lock(&endpoints_lock);
    hash_insert(endpoints, e);
    mutex_unlock(&endpoints_lock);

    *prot_data = e;

    return 0;
}
Esempio n. 7
0
void w_event_deliver_thread(void)
{
    hal_sem_init( &we_sem, "wevent" );
    we_inited = 1;

    hal_set_thread_name("WEvent");
    hal_set_current_thread_priority(PHANTOM_SYS_THREAD_PRIO+1);

    while(1)
    {
        hal_sem_acquire( &we_sem ); // TODO need some 'acquire_all' method to eat all releases

    restart:
        w_lock();

        window_handle_t w;

        queue_iterate_back(&allwindows, w, drv_video_window_t *, chain)
        {
            if( w->events_count )
            {
                if(w->eventDeliverSema)
                    hal_sem_release(w->eventDeliverSema);

                if(w->inKernelEventProcess)
                {
                    w_unlock();
                    w_do_deliver_event(w);
                    goto restart;
                }
            }
        }

        w_unlock();
    }
}
static void start_paint_thread(void)
{
    hal_sem_init( &paint_sem, "paint" );
    paint_tid = hal_start_thread( paint_thread, 0, 0 );
}
Esempio n. 9
0
// type is IF_TYPE_LOOPBACK, IF_TYPE_ETHERNET
//int if_register_interface(const char *path, ifnet **_i)
int if_register_interface(int type, ifnet **_i, phantom_device_t *dev)
{
    ifnet *i;
    //int type;
    int err;
    ifaddr *address;

    i = kmalloc(sizeof(ifnet));
    if(!i) {
        err = ERR_NO_MEMORY;
        goto err;
    }
    memset(i, 0, sizeof(ifnet));

    i->dev = dev;

    if(dev != 0 && (i->dev->dops.write == 0 || i->dev->dops.read == 0) )
        panic("dev has no read or write!");



    /* open the device * /
     if(!strcmp(path, "loopback")) {
     // the 'loopback' device is special
     type = IF_TYPE_LOOPBACK;
     i->fd = -1;
     } else {
     i->fd = sys_open(path, 0);
     if(i->fd < 0) {
     err = i->fd;
     goto err1;
     }
     // find the device's type
      err = sys_ioctl(i->fd, IOCTL_NET_IF_GET_TYPE, &type, sizeof(type));
      if(err < 0) {
      goto err2;
      }
      } */

    // find the appropriate function calls to the link layer drivers
    switch(type) {
    case IF_TYPE_LOOPBACK:
        i->link_input = &loopback_input;
        i->link_output = &loopback_output;
        i->mtu = 65535;
        break;
    case IF_TYPE_ETHERNET:

        assert(dev);

        i->link_input = &ethernet_input;
        i->link_output = &ethernet_output;
        i->mtu = ETHERNET_MAX_SIZE - ETHERNET_HEADER_SIZE;

        /* bind the ethernet link address */
        address = kmalloc(sizeof(ifaddr));
        address->addr.len = 6;
        address->addr.type = ADDR_TYPE_ETHERNET;

        if( dev->dops.get_address == 0 )
        {
            err = ERR_NET_GENERAL;
            kfree(address);
            goto err2;
        }

        err = dev->dops.get_address(dev, &address->addr.addr[0], 6);
        if(err < 0) {
            err = ERR_NET_GENERAL;
            kfree(address);
            goto err2;
        }

        /*err = sys_ioctl(i->fd, IOCTL_NET_IF_GET_ADDR, &address->addr.addr[0], 6);
        if(err < 0) {
            kfree(address);
            goto err2;
        }*/

        address->broadcast.len = 6;
        address->broadcast.type = ADDR_TYPE_ETHERNET;
        memset(&address->broadcast.addr[0], 0xff, 6);
        address->netmask.type = ADDR_TYPE_NULL;
        if_bind_link_address(i, address);
        break;
    default:
        err = ERR_NET_GENERAL;
        goto err1;
    }

    i->id = ATOMIC_ADD_AND_FETCH(&next_id, 1);
    //strlcpy(i->path, path, sizeof(i->path));
    i->type = type;
    i->rx_thread = -1;
    i->tx_thread = -1;

    //i->tx_queue_sem = sem_create(0, "tx_queue_sem");
    hal_sem_init( &(i->tx_queue_sem), "IF TX sem" );
    hal_mutex_init(&i->tx_queue_lock, "IF TX Q");
    fixed_queue_init(&i->tx_queue, TX_QUEUE_SIZE);

    mutex_lock(&ifhash_lock);
    hash_insert(ifhash, i);
    mutex_unlock(&ifhash_lock);

    // don't need threads for loopback if
    if(type != IF_TYPE_LOOPBACK)
    {
        /* start the rx and tx threads on this interface */
        err = if_boot_interface(i);
        if(err < 0)
            goto err2;

        //bootp(i);
    }
    *_i = i;


    return NO_ERROR;

err2:
    //sys_close(i->fd);
err1:
    kfree(i);
err:
    return err;
}
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;
}
phantom_device_t * driver_isa_mipsnet_probe( int port, int irq, int stage )
{
    (void) stage;
    SHOW_FLOW( 0, "Looking for MipsNet at 0x%x", port );

    if( mipsnet_probe(port) )
    {
        SHOW_ERROR( 1, "failed for port 0x%X", port );
        return 0;
    }


    phantom_device_t * dev = calloc(1, sizeof(phantom_device_t));
    assert(dev != 0);

    dev->name = "NE2000";
    dev->seq_number = seq_number++;

    dev->iobase = port;
    dev->irq = irq;
    dev->iomem = 0; // TODO map mem

    //dev->dops.stop = mipsnet_disable;
    dev->dops.read = mipsnet_read;
    dev->dops.write = mipsnet_write;
    dev->dops.get_address = mipsnet_get_address;

    dev->drv_private = calloc( 1, sizeof(struct mipsnet));
    assert( dev->drv_private != 0 );

    struct mipsnet *pvt = dev->drv_private;

    //hal_sem_init( &(pvt->reset_sem), "Ne2kReset" );

    hal_sem_init( &(pvt->recv_interrupt_sem), "mipsRecv" );
    hal_sem_init( &(pvt->send_interrupt_sem), "mipsSend" );

    mipsnet_reset(dev);

    if( hal_irq_alloc( irq, &mipsnet_interrupt, dev, HAL_IRQ_SHAREABLE ) )
    {
        SHOW_ERROR( 0, "IRQ %d is busy", irq );
        //goto free2;
    //free2:
        free(dev->drv_private);
        free(dev);
        return 0;
    }

    //pvt->thread = hal_start_kernel_thread_arg( mipsnet_thread, dev );

    //mipsnet_ei(dev);

    //pvt->active = 1;


    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;
}