//gestore degli interrupt void int_handler(){ interruptStart = getTODLO(); //tempo in cui comincia la gestione dell'interrupt, da //assegnare poi ad un eventuale processo svegliato dall'interrupt state_t *returnState = (state_t*) INT_OLDAREA; returnState->pc -= 4; if( current_process != NULL){ copy_state( returnState, ¤t_process->p_s ); current_process->userTime += interruptStart - userTimeStart;//se c'è un processo aggiorno il suo userTime current_process->CPUTime += interruptStart - CPUTimeStart; } int cause = getCAUSE(); if(CAUSE_IP_GET(cause, IL_TIMER)){ if( current_timer == PSEUDO_CLOCK ){ while( devSem[CLOCK_SEM] < 0 ){ //Ad ogni pseudo clock tick mi assicuro che il semaforo sia sempre a zero verhogen( &devSem[CLOCK_SEM], 1, 0, getTODLO() - interruptStart); } } else if(current_timer == TIME_SLICE ){ if( current_process != NULL ){ insertProcQ( priority_queue(current_process->priority), current_process); current_process->CPUTime += getTODLO() - interruptStart; //se metto in pausa il processo aggiorno anche il suo CPUTime current_process = NULL; } } } else if(CAUSE_IP_GET(cause, IL_DISK)){ dtnp_interrupt(IL_DISK); } else if(CAUSE_IP_GET(cause, IL_TAPE)){ dtnp_interrupt(IL_TAPE); } else if(CAUSE_IP_GET(cause, IL_ETHERNET)){ dtnp_interrupt(IL_ETHERNET); } else if(CAUSE_IP_GET(cause, IL_PRINTER)){ dtnp_interrupt(IL_PRINTER); } else if(CAUSE_IP_GET(cause, IL_TERMINAL)){ terminal_interrupt(); } scheduler(); }
void sysBpHandler(){ int cause; int mode; //1-dovremmo salvare lo stato del registro //2-boh -> il tipo dice per evitare loop syscall :/ currentProcess->p_s.cpsr += //qualcosa; //3-prendiamo il mode mode= ((sysBp_old->cpsr & STATUS_SYS_MODE) >> 0x3); //forse funziona -> STATUS_SYS_MODE in uarmConst.h //4-cause interrupt cause=getCAUSE(); if(cause == EXC_SYSCALL){ //caso system call //controlla se è in user mode if(mode==TRUE){ //è definito da qualche parte il true? //controllo se è una delle 11 syscall if((sysBp_old->reg_a0 >= 1) && (sysBp_old->reg_a0 <= SYSCALL_MAX)){ //SYSCALL_MAX sta in const.h sysBp_old->CP15_Cause = setCAUSE(); //siamo sicuri non ci vadano parametri? //salva il sysbp old in pgmtrap old pgmTrapHandler(); } else{ //ERRORE!!! FACCIAMO UN ALTRA VOLTA!!! } } else{//caso kernel mode int ret; /* Salva i parametri delle SYSCALL */ U32 argv1 = sysBp_old->a2; U32 argv2 = sysBp_old->a3; U32 argv3 = sysBp_old->a4; /* Gestisce ogni singola SYSCALL */ switch(sysBp_old->a1) { case CREATEPROCESS: //currentProcess->p_state.reg_v0 = createProcess((state_t *) arg1); break; case TERMINATEPROCESS: //ris = terminateProcess((int) arg1); //if(currentProcess != NULL) currentProcess->p_state.reg_v0 = ris; break; case SEMOP: semaphoreOperation((int *) argv1, (int) argv2); break; case SPECSYSHDL: break; case SPECTLBHDL: break; case SPECPGMTHDL: break; case EXITTRAP: break; case GETCPUTIME: //currentProcess->p_state.reg_v0 = getCPUTime(); break; case WAITCLOCK: //waitClock(); break; case IODEVOP: break; case GETPID: currentProcess->p_state.reg_v0 = getPid(); break; /* case WAITIO: currentProcess->p_state.reg_v0 = waitIO((int) arg1, (int) arg2, (int) arg3); break; case GETPPID: currentProcess->p_state.reg_v0 = getPpid(); break; case SPECTLBVECT: specTLBvect((state_t *) arg1, (state_t *)arg2); break; case SPECPGMVECT: specPGMvect((state_t *) arg1, (state_t *)arg2); break; case SPECSYSVECT: specSYSvect((state_t *) arg1, (state_t *)arg2); break; */ default: /* Se non è già stata eseguita la SYS12, viene terminato il processo corrente */ if(currentProcess->ExStVec[ESV_SYSBP] == 0) { int ris; ris = terminateProcess(-1); if(currentProcess != NULL) currentProcess->p_state.reg_v0 = ris; } /* Altrimenti viene salvata la SysBP Old Area all'interno del processo corrente */ else { saveCurrentState(sysBp_old, currentProcess->sysbpState_old); LDST(currentProcess->sysbpState_new); } } scheduler(); } } else{ //caso breakpoint } }