/** @brief This function handles a system call request coming from a process running in User Mode. @return Void. */ HIDDEN void syscallUserMode() { /* [Case 1] A privileged system call has been raised */ if (SYSBP_Old->a1 > 0 && SYSBP_Old->a1 < 9) { /* Save SYS/BP Old Area into PgmTrap Old Area */ saveCurrentState(SYSBP_Old, PGMTRAP_Old); /* Set program trap cause to RI (Reserved Instruction) */ PGMTRAP_Old->CP15_Cause = CAUSE_EXCCODE_SET(PGMTRAP_Old->CP15_Cause, EXC_RESERVEDINSTR); /* Call the trap handler in order to trigger the PgmTrap exception response */ pgmTrapHandler(); } /* [Case 2] A non privileged system call has been raised */ else /* Distinguish whether SYS5 has been invoked or not */ checkSYS5(SYSBK_EXCEPTION, SYSBP_Old); }
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 } }