/*************************************************************************
* *
* Memory Management Trap Handler *
* *
* realizzato dal Gruppo 17 di Lab2 Anno Accademico 1995/96 *
* *
* Lorenzo Claudio Valerio Riccardo Emiliano *
* Coronati Lanconelli Paolini Solmi Trentini *
* *
**************************************************************************/
#include "../h/supconst.h"
#include "../h/tproc.h"
#include "../h/memory.h"
#include "../h/services.e"
#include "../h/supglobals.e"
/***
* Il memmant e` uno per ogni T-process e si occupa di intercettare le
* trap causate dagli accessi in memoria non validi. Quando riceve il
* controllo guarda il tipo di trap ricevuta. Notare che l'unica trap
* recuperabile e` "page missing", in tutti gli altri casi termina il
* T-process (dopo aver stampato un messaggio di errore sul terminale).
* In caso di "page missing" ricava il SEGNO e il PAGENO dal registro
* PS2; se il SEGNO e` 0 o 1 termina il T-process anche in questo caso
* poiche` significa un accesso illegittimo ai dati del nucleo. In caso
* contrario ricava il puntatore al PD della pagina che ha causato la
* trap e forma un msg da spedire al page_process (processo servente)
* che contiene il puntatore al page descriptor, e le informazioni per
* determinare il blocco immagine all'interno dell'area di scambio.
* Attende la risposta dal processo servente.
* Risveglia il thread che ha causato la trap.
***/
extern thr_t *pager_proc;
void
memmant()
{
register thr_t *sender; /* R4 */
register union {state_t *st; pgmsg_t *pm} msg; /* R3 */
register int term_no; /* R2 inizializzato al numero di terminale */
pgmsg_t pagemsg;
thr_t *client;
tproc_t *tproc;
/* inizializzazione dati del gestore */
tproc = tprocTable + term_no;
while(TRUE)
{
sender = ANYSENDER;
DO_MSGRECV();
client = sender;
switch (msg.st->s_ps2.p2_mm.mm_typ)
{
case PAGEMISS:
if (msg.st->s_ps2.p2_mm.mm_seg > SUP1SEG)
{
if (msg.st->s_ps2.p2_mm.mm_seg == PRIVSEG)
{
pagemsg.pd = tproc->T_segPpagetable + msg.st->s_ps2.p2_mm.mm_pg;
pagemsg.segidx = term_no + 1;
}
else
{
pagemsg.pd = segSpagetable + msg.st->s_ps2.p2_mm.mm_pg;
pagemsg.segidx = 0;
}
pagemsg.pageno = msg.st->s_ps2.p2_mm.mm_pg;
/* manda la richiesta al processo servente */
sender = pager_proc;
msg.pm = &pagemsg;
DO_MSGSEND();
DO_MSGRECV();
}
else
killTerminal(term_no, "Support error: nucleus accessed");
break;
case ACCESSPROT:
killTerminal(term_no, "Segmentation violation");
break;
case INVPAGE:
killTerminal(term_no, "Invalid page number");
break;
case SEGMISS:
killTerminal(term_no, "Segmentation fault");
break;
default:
killTerminal(term_no, "Unknown memory trap");
break;
}
sender = client;
DO_MSGSEND();
}
}