示例#1
0
//gestore degli interrupt per i terminali
void terminal_interrupt(){	
	termreg_t *dev_t;
	int i ;
	memaddr *interrupt_line = (memaddr*) CDEV_BITMAP_ADDR(IL_TERMINAL);	//ottengo la linea di interrupt per i terminali
	int dev_num = pending_interrupt_device(interrupt_line);	//ottengo il terminale su cui pende l'interrupt
	dev_t = (termreg_t*) DEV_REG_ADDR(IL_TERMINAL, dev_num);	//ottengo il registro del terminale
	unsigned int status ;      //valore da far ritornare alla SYS8
	status_iprint = dev_t->transm_status;
	if( (dev_t->transm_status & DEV_TERM_STATUS ) == DEV_TTRS_S_CHARTRSM){
		//trattasi di una scrittura, priorità più alta della lettura
		status = dev_t->transm_status;
		i = devSemIndex(IL_TERMINAL+1, dev_num);
		dev_t->transm_command = DEV_C_ACK;	//acknowledgement
		if( devSem[i] < 1 ){				//se ci sono dei processi bloccati sul semaforo
			verhogen(&devSem[i], 1, status, getTODLO() - interruptStart);	//li libero e passo loro lo status register
			devStatus[i] = 0;
		}
		else{	//se nessuno sta aspettando l'interrupt salvo lo status register per quando qualcuno lo richiederà
			devStatus[i] = dev_t->transm_status;
			interruptTime[i] = getTODLO() - interruptStart;	//tempo impegato a gestire l'interrupt
		}
	}
	else if( (dev_t->recv_status & DEV_TERM_STATUS) == DEV_TRCV_S_CHARRECV ){
		//trattasi di una lettura
		status = dev_t->recv_status;
		i = devSemIndex(IL_TERMINAL, dev_num);
		dev_t->recv_command = DEV_C_ACK;	//acknowledgement
		if( devSem[i] < 1 ){
			verhogen(&devSem[i], 1,status, getTODLO() - interruptStart);	//come sopra
			devStatus[i] = 0;
		}
		else{
			devStatus[i] = dev_t->recv_status;
			interruptTime[i] = getTODLO() - interruptStart;	//tempo impegato a gestire l'interrupt
		}
	}
	
}
示例#2
0
/**
@brief This function handles a system call request coming from a process running in Kernel Mode.
@return Void.
*/
HIDDEN void syscallKernelMode()
{
	/* Identify and handle the system call */
	switch (SYSBP_Old->a1)
	{
		case CREATEPROCESS:
			CurrentProcess->p_s.a1 = createProcess((state_t *) SYSBP_Old->a2);
			break;

		case TERMINATEPROCESS:
			terminateProcess();
			break;

		case VERHOGEN:
			verhogen((int *) SYSBP_Old->a2);
			break;

		case PASSEREN:
			passeren((int *) SYSBP_Old->a2);
			break;

		case GETCPUTIME:
			CurrentProcess->p_s.a1 = getCPUTime();
			break;

		case WAITCLOCK:
			waitClock();
			break;

		case WAITIO:
			CurrentProcess->p_s.a1 = waitIO((int) SYSBP_Old->a2, (int) SYSBP_Old->a3, (int) SYSBP_Old->a4);
			break;

		case SPECTRAPVEC:
			specTrapVec((int) SYSBP_Old->a2, (state_t *) SYSBP_Old->a3, (state_t *) SYSBP_Old->a4);
			break;

		default:
			/* Distinguish whether SYS5 has been invoked or not */
			checkSYS5(SYSBK_EXCEPTION, SYSBP_Old);
	}

	/* Call the scheduler */
	scheduler();
}
示例#3
0
//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, &current_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();
}
示例#4
0
//disk, tape, network, printer interrupt handler
void dtnp_interrupt(int int_line){	
	dtpreg_t *dev_g;
	int i;
	unsigned int status;		//valore da far ritornare alla SYS8
	memaddr *interrupt_line = (memaddr*) CDEV_BITMAP_ADDR(int_line);	//ottengo la linea di interrupt
	int dev_num = pending_interrupt_device(interrupt_line);	//ottengo il device su cui pende l'interrupt
	dev_g = (dtpreg_t*) DEV_REG_ADDR(int_line, dev_num);
	dev_g->command = DEV_C_ACK;	//passo l'acknowledgement
	i = devSemIndex(int_line, dev_num) ;
	if( devSem[i] < 1 ){				//se ci sono dei processi bloccati sul semaforo
		status = dev_g->status;			//li libero e passo loro lo status register e il tempo di gestione
		verhogen( &devSem[i] , 1 , status,  getTODLO() - interruptStart);
		devStatus[i] = 0;
	}
	else{	//se nessuno sta aspettando l'interrupt salvo lo status register e il tempo di gestione dell'interrupt
		// per quando qualcuno li richiederà
		devStatus[i] = dev_g->status;
		interruptTime[i] = getTODLO() - interruptStart;
	}
}
示例#5
0
void sysBpHandler(){
	saveStateIn(sysbp_old, &currentProcess->p_s);
	unsigned int cause = CAUSE_EXCCODE_GET(sysbp_old->CP15_Cause);
	unsigned int a0 = (*sysbp_old).a1;
	unsigned int a1 = (*sysbp_old).a2;
	unsigned int a2 = (*sysbp_old).a3;
	unsigned int a3 = (*sysbp_old).a4;
	/* Se l'eccezione è di tipo System call */
	if(cause==EXC_SYSCALL){
    	/* Se il processo è in kernel mode gestisce adeguatamente */
    	if( (currentProcess->p_s.cpsr & STATUS_SYS_MODE) == STATUS_SYS_MODE){
			/* Se è fra SYS1 e SYS8 richiama le funzioni adeguate */
			switch(a0){
			    case CREATEPROCESS:
			        createProcess((state_t *) a1);
			        break;
			    case TERMINATEPROCESS:
			        terminateProcess(currentProcess);
			        break;
		        case VERHOGEN:
		            verhogen((int *) a1);
			        break;
		        case PASSEREN:
		            passeren((int *) a1);
			        break;
		        case SPECTRAPVEC:
		            specExStVec((int) a1, (state_t *) a2, (state_t *) a3);
			        break;
		        case GETCPUTIME:
		            getCPUTime();
			        break;
		        case WAITCLOCK:
		            waitForClock();
			        break;
		        case WAITIO:
		            waitForIO((int) a1, (int) a2, (int) a3);
			        break;
			    /* Altrimenti la gestione viene passata in alto */
			    default:
			        useExStVec(SPECSYSBP);
				break;            
			}
			
		    /* Richiamo lo scheduler */
		    scheduler();
		/* Se invece è in user mode */
		} else if((currentProcess->p_s.cpsr & STATUS_USER_MODE) == STATUS_USER_MODE){
			/* Se è una system call */
			if(a0 >= CREATEPROCESS && a0 <= WAITIO){
			    /* Gestisco come fosse una program trap */
			    saveStateIn(sysbp_old, pgmtrap_old);
			    /* Setto il registro cause a Reserved Instruction */
			    pgmtrap_old->CP15_Cause = CAUSE_EXCCODE_SET(pgmtrap_old->CP15_Cause, EXC_RESERVEDINSTR);
			    /* Richiamo l'handler per le pgmtrap */
			    pgmHandler();
			} else {
				useExStVec(SPECSYSBP);
			}
		}
	/* Altrimenti se l'eccezione è di tipo BreakPoint */
	} else if(cause == EXC_BREAKPOINT){
		useExStVec(SPECSYSBP);
	}

	PANIC();
}