Ejemplo n.º 1
0
/* We assign these to dummy to deal with an sdcc bug (should be fixed in next
   SDCC) */
void platform_interrupt(void)
{
  uint8_t dummy;
  uint8_t irq = *((volatile uint8_t *)0x37E0);

  tty_interrupt();
  kbd_interrupt();

  if (irq & 0x40)
    dummy = sdcc_bug_2753(*((volatile uint8_t *)0x37EC));
  if (irq & 0x80) {	/* FIXME??? */
    timer_interrupt();
    dummy = sdcc_bug_2753(*((volatile uint8_t *)0x37E0));	/* Ack the timer */
  }
}
Ejemplo n.º 2
0
Archivo: kbd.c Proyecto: wm4/kernel
static void kbd_irq_thread_proc(void* arg)
{
    kbd_irq_handler = irq_handler_register_thread(1, IRQ_TYPE_EDGE_PRE_ACK);
    if (!kbd_irq_handler)
        fatal("couldn't register IRQ");
    
    KbdState* kbd_state = kbd_create();
    if (!kbd_state)
        fatal("out of memory");
    
    bool kdebug_hotkey_state = false;
    
    for (;;) {
        uint c = irq_handler_wait_for_irq(kbd_irq_handler);
        if (!c)
            fatal("huh");
        
        kbd_interrupt(kbd_state);
        KbdKeyEvent event;
        
        if (kbd_read_event(kbd_state, &event)) {
            //keyboard event, handle it
            
            //virtual console switching
            if (event.key_code >= KEYCODE_F1
                && event.key_code <= KEYCODE_F0 + 11)
            {
                VirtualConsole* vc =
                    virtual_console_find_by_number(event.key_code - KEYCODE_F0);
                if (vc)
                    virtual_console_switch_to(vc);
                continue;
            }
            
            if (event.key_code == KEYCODE_PAGEDOWN) {
                if (event.down)
                    virtual_console_current_page_down();
                continue;
            }
            if (event.key_code == KEYCODE_PAGEUP) {
                if (event.down)
                    virtual_console_current_page_up();
                continue;
            }
            
            if (event.key_code == KEYCODE_KERNELDEBUGGER) {
                //special key: drop into kernel debugger (always...)
                if (event.down && !kdebug_hotkey_state) {
                    kdebug_hotkey_state = true;
                    kdebug_enter_by_hotkey();
                } else if (!event.down) {
                    kdebug_hotkey_state = false;
                }
            }
            
            //insert into buffer
            spinlock_lock(&buffer_lock);
                if (buffer_size < KEY_BUFFER_COUNT) {
                    key_buffer[(buffer_cur+buffer_size) % KEY_BUFFER_COUNT]
                        = event;
                    buffer_size++;
                } else {
                    printf("Kbd: Kernel keyboard buffer full!\n");
                }
            spinlock_unlock(&buffer_lock);
            
            //check workqueue for new waiters
            for (;;) {
                WorkItem* cur = workqueue_nowait(kbd_queue);
                if (!cur)
                    break;
                KbdKeyMessage* curmsg = cur->data;
                list_insert_tail(&g_kbd_waiters, curmsg);
            }
            
            //find a thread that is on the current VC (if there are several,
            //it's undefined which one will get the key)
            
            for (KbdKeyMessage* cur = list_head(&g_kbd_waiters); cur;
                 cur = list_next(&g_kbd_waiters, cur))
            {
                if (virtual_console_get_thread_vc(cur->sender)
                    == virtual_console_get_current())
                {
                    list_remove(&g_kbd_waiters, cur);
                    //wakeup in order to make him read the buffer
                    thread_wakeup_safe(cur->sender, &wait_for_kbd);
                    break;
                }
            }
            
        } //if event
    } //main loop
}
Ejemplo n.º 3
0
void platform_interrupt(void)
{
    kbd_interrupt();
    timer_interrupt();
}