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; }
static void common_thread_init(phantom_thread_t *t, int stacksize ) { //t->thread_flags = 0; t->priority = THREAD_PRIO_NORM; t->cpu_id = GET_CPU_ID(); #if CONF_NEW_CTTY t_make_ctty( t ); #else if( 0 == t->ctty ) t->ctty = wtty_init( WTTY_SMALL_BUF ); #endif // malloc uses mutex, so we have to use physalloc which is protected with spinlocks physaddr_t pa; t->stack_size = stacksize; //t->stack = calloc( 1, stacksize ); hal_pv_alloc( &pa, &(t->stack), stacksize+PAGE_SIZE ); hal_page_control( pa, t->stack, page_unmap, page_noaccess ); // poor man's guard page - TODO support in page fault t->stack_pa = pa; SHOW_FLOW( 5, "main stk va %p pa %p", t->stack, (void *)pa ); //assert(t->stack != 0); t->kstack_size = stacksize; //t->kstack = calloc( 1, stacksize ); hal_pv_alloc( &pa, &(t->kstack), stacksize+PAGE_SIZE ); hal_page_control( pa, t->kstack, page_unmap, page_noaccess ); // poor man's guard page - TODO support in page fault t->kstack_pa = pa; SHOW_FLOW( 5, "kern stk va %p pa %p", t->kstack, (void *)pa ); #if ARCH_mips // On mips we need unmapped kernel stack for mapping on MIPS is // done with exceptions too and unmapped stack is fault forever. // We achieve this by setting stack virtual address to its // physical address | 0x8000000 - this virt mem area is direct // mapped to physmem at 0 assert( (addr_t)phystokv(t->kstack_pa) > 0x80000000 ); assert( (addr_t)phystokv(t->kstack_pa) < 0xC0000000 ); t->kstack_top = phystokv(t->kstack_pa) +t->kstack_size-4; // Why -4? #else t->kstack_top = t->kstack+t->kstack_size-4; // Why -4? #endif //assert(t->kstack != 0); t->owner = 0; //t->u = 0; t->pid = NO_PID; t->thread_flags = 0;; t->waitcond = 0; hal_spin_init( &(t->waitlock)); queue_init(&(t->chain)); queue_init(&(t->runq_chain)); t->sw_unlock = 0; t->preemption_disabled = 0; }
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 ); } }