Beispiel #1
0
/*
 * For now, we just set a flag that the driver
 * can busy-wait for.
 */
static void Floppy_Interrupt_Handler(struct Interrupt_State* state)
{
    Begin_IRQ(state);
    Debug("Floppy_Interrupt_Handler!\n");
    s_interruptOccurred = 1;
    End_IRQ(state);
}
Beispiel #2
0
void Timer_Interrupt_Handler(struct Interrupt_State *state) {
    int i;
    int id;
    struct Kernel_Thread *current = CURRENT_THREAD;

    Begin_IRQ(state);

    id = Get_CPU_ID();

    if(!id) {
        /* Update global number of ticks - only on core 0 so won't count a rate equal to number of cores */
        ++g_numTicks;
    }


    /* Update per-thread number of ticks and per core ticks */
    ++current->numTicks;
    ++current->totalTime;
    CPUs[id].ticks++;

    /*
     * If thread has been running for an entire quantum,
     * inform the interrupt return code that we want
     * to choose a new thread.
     */
    if(!id) {
        // XXXX - only core #0 is currently handling new timer events
        /* update timer events */
        for(i = 0; i < timeEventCount; i++) {
            if(pendingTimerEvents[i].ticks == 0) {
                if(timerDebug)
                    Print("timer: event %d expired (%d ticks)\n",
                          pendingTimerEvents[i].id,
                          pendingTimerEvents[i].origTicks);
                (pendingTimerEvents[i].callBack) (pendingTimerEvents[i].
                                                  id);
            } else {
                if(timerDebug)
                    Print("timer: event %d at %d ticks\n",
                          pendingTimerEvents[i].id,
                          pendingTimerEvents[i].ticks);
                pendingTimerEvents[i].ticks--;
            }
        }
    }
    if(current->numTicks >= g_Quantum) {
        g_needReschedule[id] = true;
        // TODO:
        /*
         * The current process is moved to a lower priority queue,
         * since it consumed a full quantum.
         */
    }

    End_IRQ(state);
}
Beispiel #3
0
static void NE2000_Interrupt_Handler(struct Interrupt_State *state) {
    struct Net_Device *device;
    ulong_t baseAddr;
    unsigned char isrMask;
    int rc;

    Begin_IRQ(state);
    DEBUG_NE2K("Handling NE2000 interrupt\n");

    rc = Get_Net_Device_By_IRQ(state->intNum - FIRST_EXTERNAL_INT, &device);
    if (rc != 0) {
        Print("NE2000: Could not identify interrupt number %d\n",
              state->intNum);
        goto fail;
    }

    baseAddr = device->baseAddr;
    isrMask = In_Byte(NE2K0R_ISR + baseAddr);

    // DEBUG_NE2K("ISR Mask: %x\n" , isrMask);

    if (isrMask & NE2K_ISR_RXE) {
        //Print("RSR: %x\n", In_Byte(NE2K0R_RSR + baseAddr));
        ++device->rxPacketErrors;
    }

    if (isrMask & NE2K_ISR_TXE) {
        //Print("TSR: %x\n", In_Byte(NE2K0R_TSR + baseAddr));
        ++device->txPacketErrors;
    }

    if (isrMask & NE2K_ISR_OVW) {
        //Print("Ring Buffer Overflow Encountered!!\n");
        NE2000_Handle_Ring_Buffer_Overflow(device);
    }

    if (isrMask & NE2K_ISR_PRX) {
        DEBUG_NE2K("Receiving packet\n");
        NE2000_Do_Receive(device);
        ++device->rxPackets;
    }

    if (isrMask & NE2K_ISR_PTX) {
        //Print("Packet transmitted\n");
        DEBUG_NE2K("Transmitted.\n");
        //Print("TSR: %x\n", In_Byte(NE2K0R_TSR + baseAddr));
        ++device->txPackets;
    }

  fail:

    Out_Byte(baseAddr + NE2K0R_ISR, isrMask);

    End_IRQ(state);
}
Beispiel #4
0
/*
 * Temporary timer interrupt handler used to calibrate
 * the delay loop.
 */
static void Timer_Calibrate(struct Interrupt_State *state) {
    Begin_IRQ(state);
    if(g_numTicks < CALIBRATE_NUM_TICKS)
        ++g_numTicks;
    else {
        /*
         * Now we can look at EAX, which reflects how many times
         * the loop has executed
         */
        /*Print("Timer_Calibrate: eax==%d\n", state->eax); */
        s_spinCountPerTick = INT_MAX - state->eax;
        state->eax = 0;         /* make the loop terminate */
    }
    End_IRQ(state);
}
Beispiel #5
0
static void rtl8139_interrupt( struct Interrupt_State * state )
{
	Begin_IRQ(state);

	uint_t status = In_Word(RTL8139_ISR);

	PrintBoth("Interrupt Received: %x\n", status);

	if( status == PKT_RX )
		rtl8139_Receive();

	rtl8139_Clear_IRQ(status);
	End_IRQ(state);

}
Beispiel #6
0
static void Timer_Interrupt_Handler(struct Interrupt_State *state) {
    int i;
    struct Kernel_Thread *current = g_currentThread;

    Begin_IRQ(state);

    /* Update global and per-thread number of ticks */
    ++g_numTicks;
    ++current->numTicks;

    /* update timer events */
    for (i = 0; i < timeEventCount; i++) {
        if (pendingTimerEvents[i].ticks == 0) {
            if (timerDebug)
                Print("timer: event %d expired (%d ticks)\n",
                      pendingTimerEvents[i].id,
                      pendingTimerEvents[i].origTicks);
            (pendingTimerEvents[i].callBack) (pendingTimerEvents[i].id);
        } else {
            pendingTimerEvents[i].ticks--;
        }
    }

    /*
     * If thread has been running for an entire quantum,
     * inform the interrupt return code that we want
     * to choose a new thread.
     */
    if (current->numTicks >= g_Quantum) {
        g_needReschedule = true;
        // TODO:
        /*
         * The current process is moved to a lower priority queue,
         * since it consumed a full quantum.
         */
    }

    End_IRQ(state);
}
Beispiel #7
0
/*
 * Handler for keyboard interrupts.
 */
static void Keyboard_Interrupt_Handler(struct Interrupt_State* state)
{
    uchar_t status, scanCode;
    unsigned flag = 0;
    bool release = false, shift;
    Keycode keycode;

    Begin_IRQ(state);

    status = In_Byte(KB_CMD);
    IO_Delay();

    if ((status & KB_OUTPUT_FULL) != 0) {
	/* There is a byte available */
	scanCode = In_Byte(KB_DATA);
	IO_Delay();
/*
 *	Print("code=%x%s\n", scanCode, (scanCode&0x80) ? " [release]" : "");
 */

	if (scanCode & KB_KEY_RELEASE) {
	    release = true;
	    scanCode &= ~(KB_KEY_RELEASE);
	}

	if (scanCode >= SCAN_TABLE_SIZE) {
	    Print("Unknown scan code: %x\n", scanCode);
	    goto done;
	}

	/* Process the key */
	shift = ((s_shiftState & SHIFT_MASK) != 0);
	keycode = shift ? s_scanTableWithShift[scanCode] : s_scanTableNoShift[scanCode];

	/* Update shift, control and alt state */
	switch (keycode) {
	case KEY_LSHIFT:
	    flag = LEFT_SHIFT;
	    break;
	case KEY_RSHIFT:
	    flag = RIGHT_SHIFT;
	    break;
	case KEY_LCTRL:
	    flag = LEFT_CTRL;
	    break;
	case KEY_RCTRL:
	    flag = RIGHT_CTRL;
	    break;
	case KEY_LALT:
	    flag = LEFT_ALT;
	    break;
	case KEY_RALT:
	    flag = RIGHT_ALT;
	    break;
	default:
	    goto noflagchange;
	}

	if (release)
	    s_shiftState &= ~(flag);
	else
	    s_shiftState |= flag;
			
	/*
	 * Shift, control and alt keys don't have to be
	 * queued, flags will be set!
	 */
	goto done;

noflagchange:
	/* Format the new keycode */
	if (shift)
	    keycode |= KEY_SHIFT_FLAG;
	if ((s_shiftState & CTRL_MASK) != 0)
	    keycode |= KEY_CTRL_FLAG;
	if ((s_shiftState & ALT_MASK) != 0)
	    keycode |= KEY_ALT_FLAG;
	if (release)
	    keycode |= KEY_RELEASE_FLAG;
		
	/* Put the keycode in the buffer */
	Enqueue_Keycode(keycode);

	/* Wake up event consumers */
	Wake_Up(&s_waitQueue);

	/*
	 * Pick a new thread upon return from interrupt
	 * (hopefully the one waiting for the keyboard event)
	 */
	g_needReschedule = true;
    }

done:
    End_IRQ(state);
}
Beispiel #8
0
/*
 * Wake up any threads in the floppy wait queue.
 */
static void Floppy_Interrupt_Handler(struct Interrupt_State* state)
{
    Begin_IRQ(state);
    Wake_Up(&s_floppyInterruptWaitQueue);
    End_IRQ(state);
}