Custom-OS-Kernel / phase3 / initProc.c
initProc.c
Raw
#include "../h/initProc.h"
#include "../h/vmSupport.h"
#include "../h/sysSupport.h"

support_t userSupportStructure[UPROCMAX];
state_t userStateStructure[UPROCMAX];
int supportDeviceSemaphore[3][UPROCMAX]; // 3 device semaphores for printer, terminal receiver and terminal transmitter
int flashSemaphores[UPROCMAX]; // Semaphores to represent the flash devices

extern swap_t swapPoolTable[POOLSIZE];
extern int swapPoolSemaphore;

extern void Support_Pager();
extern void GeneralException_Handler();

int master_sem; // master semaphore

/* Function to initialize the processes */
void test(){
    initSwapStructs();
    initSemaphores();

    // Initialize and launch 8 u-procs
    for (int i=0; i < UPROCMAX; i++) {
        initProcess(i);
        //SYSCALL(PASSEREN, (int) &master_sem, 0, 0);
        /* 
           This causes the test process to remain blocked until all
           u-procs have finished executing because the P operation forces
           mutually exclusive access by keeping the master_sem negative until
           all executions are complete.
        */
    }
    
    for (int i=0; i < UPROCMAX; i++) {    //I changed code here (test() should be blocked after all 8 u-procs have been launched
    	SYSCALL(PASSEREN, (int) &master_sem, 0, 0);
    }

    SYSCALL(TERMINATE, 0, 0, 0);

}

void initSemaphores()
{

    master_sem = 0;

    for (int i=0; i < UPROCMAX; i++) {
        flashSemaphores[i] = 1;
    }

    for (int i=0; i < 3; i++) {
        for (int j=0; j < UPROCMAX; j++){
            supportDeviceSemaphore[i][j] = 1;
        }
    }  
}

void initProcess(int id)
{    
    // id is the u-proc number being launches   
    userStateStructure[id].pc_epc = 0x800000B0; // address of the start of the .text section
    userStateStructure[id].reg_t9 = 0x800000B0;
    userStateStructure[id].reg_sp = 0xC0000000;

    userStateStructure[id].status = IMON | IEPON | USERPON | TEBITON; // user mode, interrupts enabled, PLT enabled

    userStateStructure[id].entry_hi = (id + 1) << 6;

    // Initialize the u-proc's support structure
    userSupportStructure[id].sup_asid = id + 1;
    userSupportStructure[id].sup_exceptContext[0].pc = (memaddr) Support_Pager;
    userSupportStructure[id].sup_exceptContext[1].pc = (memaddr) GeneralException_Handler;

    userSupportStructure[id].sup_exceptContext[0].status = IMON | IEPON | TEBITON; // kernel mode, interrupts enabled, PLT enabled
    userSupportStructure[id].sup_exceptContext[1].status = IMON | IEPON | TEBITON; // kernel mode, interrupts enabled, PLT enabled

    memaddr ramtopValue;
    RAMTOP(ramtopValue); // assign current ramtop value
    userSupportStructure[id].sup_exceptContext[0].stackPtr = ramtopValue - (id + 1) * PAGESIZE * 2;
    userSupportStructure[id].sup_exceptContext[1].stackPtr = ramtopValue - (id + 1) * PAGESIZE * 2 + PAGESIZE;

    // Initialize the u-proc's page table
    for (int i = 0; i < MAXPAGES; i++) {
        if (i == 31) {
            // Stack page
            userSupportStructure[id].sup_privatePgTbl[i].pte_entryHI = 0xBFFFF << 12; // Each page is 4KB
        } else {
            userSupportStructure[id].sup_privatePgTbl[i].pte_entryHI = 0x80000000 + (i << 12);
        }

        // Find ASID number corresponding to the page number in tne entryHI field
        SET_ASID(userSupportStructure[id].sup_privatePgTbl[i].pte_entryHI, id + 1);
        // Page is write enabled
        userSupportStructure[id].sup_privatePgTbl[i].pte_entryLO = 0x00000400;
    }
    
    // Launch/Start u-proc
    int launchStatus = SYSCALL(CREATEPROCESS, (int) &userStateStructure[id], (int) &userSupportStructure[id], 0);

    if (launchStatus == -1) {
        SYSCALL(TERMINATE, 0, 0, 0);
    }

}