/*************************************************************************
* *
* Modulo per la gestione delle trap *
* *
* realizzato dal Gruppo 17 di Lab2 Anno Accademico 1995/96 *
* *
* Lorenzo Claudio Valerio Riccardo Emiliano *
* Coronati Lanconelli Paolini Solmi Trentini *
* *
**************************************************************************/
/*
* Alle routine di gestione viene passato in R4 l'indirizzo dell'area old
* della relativa trap ed in R3 il tipo di trap
*/
#include "../h/types.h"
#include "../h/nucconst.h"
#include "../h/globals.e"
#include "../h/sendrecv.e"
#include "../h/scheduler.e"
#include "../h/ssi.e"
#ifdef NUC_PROFILE
int sys_scount = 0;
int sys_rcount = 0;
int pass_count = 0;
#endif
/* gestore trap chiamate di sistema */
void
onSys()
{
register state_t *sts; /* R4 */
register int trap_type; /* R3 */
switch (sts->s_ps2.p2_sys.sys_no)
{
case MSGSEND:
/*
* Se la chiamata di sistema e' stata eseguita in modo kernel
* viene eseguito il servizio, altrimenti viene simulata una
* program trap per istruzione privilegiata
*/
if (sts->s_ps1.ps_ku == 1)
{
#ifdef NUC_PROFILE
sys_scount++;
#endif
msgSend(run_thread, sts->s_r[4], sts->s_r[3]);
}
else
{
sts->s_ps2.p2_pr.pr_typ = PRIVINSTR;
trap_type = PROGTRAP;
passup();
}
break;
case MSGRECV:
if (sts->s_ps1.ps_ku == 1)
{
#ifdef NUC_PROFILE
sys_rcount++;
#endif
msgRecv();
}
else
{
sts->s_ps2.p2_pr.pr_typ = PRIVINSTR;
trap_type = PROGTRAP;
passup();
}
break;
default:
passup();
break;
}
DISPATCH();
}
/* gestore trap programma e memory management */
/*
* se il processo ha un tread di gestione della trap, gli manda un
* messaggio e mette in attesa il thread che ha causato la trap,
* altrimenti lo termina
*/
void
passup()
{
register state_t *sts; /* R4 */
register int trap_type; /* R3 */
register thr_t *trap_handler;
#ifdef NUC_PROFILE
pass_count++;
#endif
#ifdef NUC_DEBUG
/* determina se la trap e` avvenuta nel nucleo */
if (nuc_stl == sts->s_stl)
{
if (trap_type == PROGTRAP)
{
switch (sts->s_ps2.p2_pr.pr_typ)
{
case ILOPCODE:
panic("Illegal opcode program trap in nucleus");
break;
case NONSUPINSTR:
panic("Non super.instr.program trap in nucleus");
break;
case PRIVINSTR:
panic("Priv.instr.program trap in nucleus");
break;
case ILLINSTR:
panic("Illegal instr.program trap in nucleus");
break;
case ODDADD:
panic("Odd address program trap in nucleus");
break;
case NONPAGEAL:
panic("Non page al.program trap in nucleus");
break;
case NONEXISTMEM:
panic("Non existent mem.program trap in nucleus");
break;
case STKLIMYELLOW:
panic("stack limit yello program trap in nucleus");
break;
case STKLIMRED:
panic("stack limit red program trap in nucleus");
break;
case ZERODIV:
panic("zero div.program trap in nucleus");
break;
default:
panic("Unknown program trap in nucleus");
break;
}
}
else if (trap_type == SYSTRAP)
panic("System trap in nucleus");
else
panic("Memory Management trap in nucleus");
}
#endif
/* verifica l'esistenza del thread gestore */
trap_handler = (&run_proc->p_prgtrap)[trap_type];
if (trap_handler == NULL)
{
termProc(run_thread);
run_proc = NULL;
}
else
{
SAVESTATE();
run_thread->t_handler = trap_handler;
msgSend(run_thread, trap_handler, &run_thread->t_s);
sleepProc(ANYTRAP);
}
schedule();
NEWSTATE();
LOADTIMER();
DISPATCH();
}