supinit.c


/*************************************************************************
*                                                                        *
*   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);
}



[INDICE CODICE]