void init_timer() { t_counter = 0; active_timer_count = 0; int i; //Clear the event timer table for(i = 0; i < 10; i++) event_timer[i].p = (process*)0; init_pic(); init_time_chip(1000); //We use this initial low speed for MIPS calc //UPDATE: As of now, we're just doing it because we want a steady ~1ms timebase for timer functions installInterrupt(TIMER_INT_NUM, &_handle_timerInt, 3); installInterrupt(0xE7, &_spurious_handler, 3); }
void do_mips_calc(void (*cb)(unsigned int)) { installInterrupt(TIMER_INT_NUM, &_calc_mips, 3); reentry_call = cb; state = 1; __asm__ ("jmp _mips_loop\n"); }
//Stop the timer, update the frequency, and turn it back on void throttle_timer(unsigned int freq) { timer_off(); init_time_chip(freq); //Full throttle is 596591 timer_on(); installInterrupt(TIMER_INT_NUM, &_handle_timerInt, 3); //Make sure the normal handler is installed }
void c_calc_mips() { static unsigned int state = 1; //Acknowledge the timer interrupt timer_int_ack(); if(state) { //We're starting up, so update the state and //re-enter the MIPS loop state = 0; __asm__ ("jmp _mips_loop\n"); } else { //Do MIPS calculation from counter and return to //kernel startup process _mips_counter = _mips_counter * 400; //4 instructions in the loop and 100Hz sample window resetProcessCounter(); installInterrupt(TIMER_INT_NUM, &_handle_timerInt, 3); //Reset the vector to the normal timer handler (*reentry_call)(_mips_counter); } }
//Open an IRQ channel on the PIC and set up the IRQ handler to pass a message to //the registered process //NOTE: irq_number is offset by one (eg: irq_number 0 implies irq 1) because //irq 0 itself is reserved for the system timer regardless. unsigned int irq_register(unsigned int irq_number, process *requesting_proc) { //Return failure if a nonsense IRQ was requested if(irq_number > 15) return 0; //map the process DEBUG("\nRegistered IRQ slot #"); DEBUG_HD(irq_number); DEBUG("/interrupt 0x"); DEBUG_HD(irq_number + 0xE0); DEBUG_PCHAR('\n'); irq_process[irq_number - 1] = requesting_proc; //map the handler into the right interrupt vector, assuming it's not //already set up (E0 is irq 0) installInterrupt(irq_number + 0xE0, irq_handler[irq_number - 1], 3); //Open up the associated PIC channel enable_irq(irq_number); //For now, we can't really fail so we just return OK return 1; }