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; }
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; }
int int_enable_irq( int shared, int irqNum, unsigned int bmAddr, unsigned int ataAddr ) { // error if interrupts enabled now // error if invalid irq number // error if bmAddr is < 100H // error if shared and bmAddr is 0 // error if ataAddr is < 100H if ( ata->int_use_intr_flag ) return 1; if ( ( irqNum < 1 ) || ( irqNum > 15 ) ) return 2; if ( irqNum == 2 ) return 2; if ( bmAddr && ( bmAddr < 0x0100 ) ) return 3; if ( shared && ( ! bmAddr ) ) return 4; if ( ataAddr < 0x0100 ) return 5; // save the input parameters //int_shared = shared; ata->int_irq_number = irqNum; ata->int_bmide_addr = bmAddr; ata->int_ata_addr = ataAddr; SHOW_INFO( 0, "IDE Set IRQ %d\n", irqNum ); if( hal_irq_alloc( irqNum, int_handler, 0, HAL_IRQ_SHAREABLE ) ) return 2; // interrupts use is now enabled ata->int_use_intr_flag = 1; //ata->int_got_it_now = 0; // Done. return 0; }
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_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; }
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; }