/*************************************************************************
* *
* Modulo: supinit.c *
* *
* realizzato dal Gruppo 17 di Lab2 Anno Accademico 1995/96 *
* *
* Lorenzo Claudio Valerio Riccardo Emiliano *
* Coronati Lanconelli Paolini Solmi Trentini *
* *
**************************************************************************/
#include "../h/types.h"
#include "../h/supconst.h"
#include "../h/supglobals.e"
extern void startt1();
extern void startd0();
extern void startd1();
extern void startb0();
extern void startb1();
extern void end();
extern void disk();
extern void timer();
extern void pager();
extern void sysservt();
HIDDEN sd_t syssegtable[NOSEGS]; /* system segment table utilizzata dai
* processi serventi */
/* inizializza un segment descriptor */
HIDDEN void
setSegDesc(sd, prot, pta)
register sd_t *sd;
int prot;
pd_t *pta;
{
sd->sd_len = NOPAGES - 1;
sd->sd_prot = prot;
sd->sd_p = TRUE;
sd->sd_pta = pta;
}
void
test()
{
register thr_t *sender;
register int msg;
unsigned int p_st,p_st1,p_sd0,p_sd1, /* nucleus in memory */
p_sb0,p_sb1,p_stck;
int term_no,seg_no,page_no; /* loop indices */
unsigned int frame_no,endmem; /* physical page number */
pd_t *pd_ptr; /* page table entry */
state_t init_state; /* used for initialization */
struct {unsigned int beg_free; unsigned int end_free} imsg;
STST(&init_state);
imsg.end_free = (unsigned)init_state.s_stl;
/* find nucleus in memory */
p_st = (unsigned)start / PAGESIZE;
p_st1 = (unsigned)startt1 / PAGESIZE;
p_sd0 = (unsigned)startd0 / PAGESIZE;
p_sd1 = (unsigned)startd1 / PAGESIZE;
p_sb0 = (unsigned)startb0 / PAGESIZE;
p_sb1 = (unsigned)startb1 / PAGESIZE;
p_stck = imsg.end_free / PAGESIZE;
/* Inizializza le tabelle di pagine */
for (page_no = 0; page_no < NOPAGES; page_no++)
{
/*
* Tabelle di pagine dei segmenti di sistema
* queste mappano tutta la memoria fisica 1:1, e
* marcano come non presenti le pagine del nucleo
*/
for (seg_no = 0; seg_no < NOSEGS; seg_no++)
{
frame_no = seg_no * NOPAGES + page_no;
pd_ptr = &syspagetable[seg_no][page_no];
if ( (p_st <= frame_no && frame_no < p_st1) ||
(p_sd0 <= frame_no && frame_no < p_sd1) ||
(p_sb0 <= frame_no && frame_no < p_sb1) ||
frame_no > p_stck )
pd_ptr->pd_p = FALSE; /* non presente */
else
{
pd_ptr->pd_frame = frame_no;
pd_ptr->pd_r = FALSE; /* non riferita */
pd_ptr->pd_m = FALSE; /* non modificata */
pd_ptr->pd_p = TRUE; /* presente */
}
}
/*
* La tabella di pagina del segmento condiviso (come quelle
* dei segmenti privati) ha inizialmente tutte le pagine non
* presenti, e man mano che sono accedute vengono allocate
*/
segSpagetable[page_no].pd_p = FALSE; /* non presente */
/* Tabelle di pagine relative al segmento privato dei T-process */
for (term_no = 0; term_no < MAXTPROC; term_no++)
tprocTable[term_no].T_segPpagetable[page_no].pd_p = FALSE;
}
/* Inizializza le tabelle dei segmenti */
/* Segmenti di sistema (utilizzati dai processi serventi) */
for (seg_no = 0; seg_no < NOSEGS; seg_no++)
setSegDesc( syssegtable+seg_no,
(seg_no <= SUP1SEG) ? READ+WRITE+EXEC : READ+WRITE,
syspagetable[seg_no] );
/* segmenti dei T-process */
for (term_no = 0; term_no < MAXTPROC; term_no++)
{
for (seg_no = 0; seg_no <= SUP1SEG; seg_no++)
{
/* I segmenti 0 e 1 sono accessibili solo al livello
* di supporto
*/
setSegDesc( &tprocTable[term_no].T_supsegtable[seg_no],
READ+WRITE+EXEC,
syspagetable[seg_no] );
setSegDesc( &tprocTable[term_no].T_usrsegtable[seg_no],
NONE,
syspagetable[seg_no] );
}
/*
* I segmenti 3 e 4 sono accessibili dal livello di supporto
* in sola lettura/scrittura, mentre dal main thread anche
* in esecuzione
*/
setSegDesc( &tprocTable[term_no].T_supsegtable[PRIVSEG],
READ+WRITE,
tprocTable[term_no].T_segPpagetable );
setSegDesc( &tprocTable[term_no].T_supsegtable[SHARSEG],
READ+WRITE,
segSpagetable );
setSegDesc( &tprocTable[term_no].T_usrsegtable[PRIVSEG],
READ+WRITE+EXEC,
tprocTable[term_no].T_segPpagetable );
setSegDesc( &tprocTable[term_no].T_usrsegtable[SHARSEG],
READ+WRITE+EXEC,
segSpagetable );
}
/* Inizializza le strutture T-process */
for (term_no = 0; term_no < MAXTPROC; term_no++)
{
tprocTable[term_no].T_parent =
tprocTable[term_no].T_process =
tprocTable[term_no].T_mainthread =
tprocTable[term_no].T_sysservt =
tprocTable[term_no].T_memmant =
tprocTable[term_no].T_progt =
tprocTable[term_no].T_syscallt = NULL;
}
/* Inizializza i processi serventi */
init_state.s_ps1.ps_m = TRUE; /* memory mapping on */
init_state.s_ps1.ps_int = 0; /* interrupt enabled */
init_state.s_sta = syssegtable;
endmem = (unsigned)end;
/* Inizializza il timer process */
init_state.s_stl = endmem;
endmem += TIMERSTKSIZE;
init_state.s_sp = endmem;
init_state.s_pc = (int)timer;
timer_proc = s_service(CREAPROC, &init_state);
/* Inizializza il disk process */
#ifdef DISK_ON
init_state.s_stl = endmem;
endmem += DISKSTKSIZE;
init_state.s_sp = endmem;
init_state.s_pc = (int)disk;
disk_proc = s_service(CREAPROC, &init_state);
#endif
/* Inizializza il pager process */
init_state.s_stl = endmem;
endmem += PAGERSTKSIZE;
init_state.s_sp = endmem;
init_state.s_pc = (int)pager;
pager_proc = s_service(CREAPROC, &init_state);
#ifdef SUP_DEBUG
if (timer_proc == NULL || pager_proc == NULL)
HALT();
#endif
/* Inizializza il SysServiceThread dei vari T-process */
for (term_no = 0; term_no < MAXTPROC; term_no++)
{
init_state.s_r[2] = term_no;
init_state.s_stl = endmem;
endmem += TERMSTKSIZE;
init_state.s_sp = init_state.s_stl + SSTSTKSIZE;
init_state.s_pc = (int)sysservt;
init_state.s_sta = tprocTable[term_no].T_supsegtable;
sender = s_service(CREAPROC, &init_state);
#ifdef SUP_DEBUG
if (sender == NULL)
HALT();
#endif
tprocTable[term_no].T_sysservt = sender;
DO_MSGSEND(); /* gli comunica chi e` che lo ha creato */
}
/* determina l'inizio della memoria disponibile per il free page pool */
imsg.beg_free = (endmem + PAGESIZE-1) & ~(PAGESIZE-1);
/* fa partire il pager process */
sender = pager_proc;
msg = &imsg;
DO_MSGSEND();
/* Attende la terminazione di tutti i T-process */
term_no = MAXTPROC;
while(term_no > 0)
{
sender = ANYSENDER;
DO_MSGRECV();
if (0 <= msg && msg < MAXTPROC)
term_no--;
}
/* shutdown */
s_service(TERMPROC, 0);
}