int main() { unsigned long i = 0, cnt = 0; unsigned char c; GPBCON = GPB7_out|GPB8_out|GPB9_out|GPB10_out; init_uart( ); //波特率57600,8N1(8个数据位,无校验位,1个停止位) DPRINTK(KERNEL_DEBUG,"\n\rkernel:enter main\n\r"); sched_init( ); // OS_ENTER_CRITICAL(); OSCreateProcess(15*1024,1024,NULL,NULL,5); DPRINTK(KERNEL_DEBUG,"\n\rkernel:first\n\r"); while(1){ // schedule(); // DPRINTK(KERNEL_DEBUG,"kernel:main\n\r"); /* if(i&1){ DPRINTK(KERNEL_DEBUG,"1\n\r"); } */ // GPBDAT = (~(++i))<<7; DPRINTK(KERNEL_DEBUG,"kernel:process 0\n\r"); wait(1000000); } return 0; }
void osInit(int argc, char *argv[]) { void *PageTable = (void *) calloc(2, NUMBER_VIRTUAL_PAGES); INT32 i; MEMORY_MAPPED_IO mmio; long ProcessID; long ErrorReturned; PCB* pcb; // Demonstrates how calling arguments are passed thru to here printf("Program called with %d arguments:", argc); for (i = 0; i < argc; i++) printf(" %s", argv[i]); printf("\n"); printf("Calling with argument 'sample' executes the sample program.\n"); // Here we check if a second argument is present on the command line. // If so, run in multiprocessor mode if (argc > 2) { if (strcmp(argv[2], "M") || strcmp(argv[2], "m")) { printf("Simulation is running as a MultProcessor\n\n"); mmio.Mode = Z502SetProcessorNumber; mmio.Field1 = MAX_NUMBER_OF_PROCESSORS; mmio.Field2 = (long) 0; mmio.Field3 = (long) 0; mmio.Field4 = (long) 0; MEM_WRITE(Z502Processor, &mmio); // Set the number of processors } } else { printf("Simulation is running as a UniProcessor\n"); printf( "Add an 'M' to the command line to invoke multiprocessor operation.\n\n"); } // Setup so handlers will come to code in base.c TO_VECTOR[TO_VECTOR_INT_HANDLER_ADDR ] = (void *) InterruptHandler; TO_VECTOR[TO_VECTOR_FAULT_HANDLER_ADDR ] = (void *) FaultHandler; TO_VECTOR[TO_VECTOR_TRAP_HANDLER_ADDR ] = (void *) svc; // Determine if the switch was set, and if so go to demo routine. PageTable = (void *) calloc(2, NUMBER_VIRTUAL_PAGES); if ((argc > 1) && (strcmp(argv[1], "sample") == 0)) { mmio.Mode = Z502InitializeContext; mmio.Field1 = 0; mmio.Field2 = (long) SampleCode; mmio.Field3 = (long) PageTable; MEM_WRITE(Z502Context, &mmio); // Start of Make Context Sequence mmio.Mode = Z502StartContext; // Field1 contains the value of the context returned in the last call mmio.Field2 = START_NEW_CONTEXT_AND_SUSPEND; MEM_WRITE(Z502Context, &mmio); // Start up the context } // End of handler for sample code - This routine should never return here // By default test0 runs if no arguments are given on the command line // Creation and Switching of contexts should be done in a separate routine. // This should be done by a "OsMakeProcess" routine, so that // test0 runs on a process recognized by the operating system. if ((argc > 1) && (strcmp(argv[1], "test0") == 0)) { mmio.Mode = Z502InitializeContext; mmio.Field1 = 0; mmio.Field2 = (long) test0; mmio.Field3 = (long) PageTable; mmio.Field4 = 0; MEM_WRITE(Z502Context, &mmio); // Start of Make Context Sequence OSCreateProcess(argv[1], mmio.Field1, 100, 0, mmio.Field4); mmio.Mode = Z502StartContext; // Field1 contains the value of the context returned in the last call mmio.Field2 = START_NEW_CONTEXT_AND_SUSPEND; MEM_WRITE(Z502Context, &mmio); // Start up the context } if ((argc > 1) && (strcmp(argv[1], "test1") == 0)) { mmio.Mode = Z502InitializeContext; mmio.Field1 = 0; mmio.Field2 = (long) test1; mmio.Field3 = (long) PageTable; mmio.Field4 = 0; InitializePCDQ(15); InitTimerQueue(15); InitReadyQueue(15); InitDiskQueue(15); MEM_WRITE(Z502Context, &mmio); // Start of Make Context Sequence OSCreateProcess(argv[1], mmio.Field1, 100, 0, mmio.Field4); mmio.Mode = Z502StartContext; // Field1 contains the value of the context returned in the last call mmio.Field2 = START_NEW_CONTEXT_AND_SUSPEND; MEM_WRITE(Z502Context, &mmio); // Start up the context } if ((argc > 1) && (strcmp(argv[1], "test2") == 0)) { mmio.Mode = Z502InitializeContext; mmio.Field1 = 0; mmio.Field2 = (long) test2; mmio.Field3 = (long) PageTable; mmio.Field4 = 0; InitializePCDQ(15); InitTimerQueue(15); InitReadyQueue(15); InitDiskQueue(15); MEM_WRITE(Z502Context, &mmio); // Start of Make Context Sequence OSCreateProcess(argv[1], mmio.Field1, 100, 0, mmio.Field4); mmio.Mode = Z502StartContext; // Field1 contains the value of the context returned in the last call mmio.Field2 = START_NEW_CONTEXT_AND_SUSPEND; MEM_WRITE(Z502Context, &mmio); // Start up the context } if ((argc > 1) && (strcmp(argv[1], "test3") == 0)) { mmio.Mode = Z502InitializeContext; mmio.Field1 = 0; mmio.Field2 = (long) test3; mmio.Field3 = (long) PageTable; mmio.Field4 = 0; InitializePCDQ(15); InitTimerQueue(15); InitReadyQueue(15); InitDiskQueue(15); MEM_WRITE(Z502Context, &mmio); // Start of Make Context Sequence OSCreateProcess(argv[1], mmio.Field1, 100, 0, mmio.Field4); mmio.Mode = Z502StartContext; // Field1 contains the value of the context returned in the last call mmio.Field2 = START_NEW_CONTEXT_AND_SUSPEND; MEM_WRITE(Z502Context, &mmio); // Start up the context } if ((argc > 1) && (strcmp(argv[1], "test4") == 0)) { mmio.Mode = Z502InitializeContext; mmio.Field1 = 0; mmio.Field2 = (long) test4; mmio.Field3 = (long) PageTable; mmio.Field4 = 0; InitializePCDQ(15); InitTimerQueue(15); InitReadyQueue(15); InitDiskQueue(15); MEM_WRITE(Z502Context, &mmio); // Start of Make Context Sequence pcb=OSCreateProcess(argv[1], mmio.Field1, 10, 0, mmio.Field4); mmio.Mode = Z502StartContext; // Field1 contains the value of the context returned in the last call mmio.Field2 = START_NEW_CONTEXT_AND_SUSPEND; MEM_WRITE(Z502Context, &mmio); // Start up the context // EnQueue(&pcb_ready_queue, (void*) pcb); // Dispatcher(); } if ((argc > 1) && (strcmp(argv[1], "test5") == 0)) { mmio.Mode = Z502InitializeContext; mmio.Field1 = 0; mmio.Field2 = (long) test5; mmio.Field3 = (long) PageTable; mmio.Field4 = 0; InitializePCDQ(15); InitTimerQueue(15); InitReadyQueue(15); InitDiskQueue(15); MEM_WRITE(Z502Context, &mmio); // Start of Make Context Sequence OSCreateProcess(argv[1], mmio.Field1, 100, 0, mmio.Field4); mmio.Mode = Z502StartContext; // Field1 contains the value of the context returned in the last call mmio.Field2 = START_NEW_CONTEXT_AND_SUSPEND; MEM_WRITE(Z502Context, &mmio); // Start up the context } if ((argc > 1) && (strcmp(argv[1], "test6") == 0)) { mmio.Mode = Z502InitializeContext; mmio.Field1 = 0; mmio.Field2 = (long) test6; mmio.Field3 = (long) PageTable; mmio.Field4 = 0; InitializePCDQ(15); InitTimerQueue(15); InitReadyQueue(15); InitDiskQueue(15); MEM_WRITE(Z502Context, &mmio); // Start of Make Context Sequence OSCreateProcess(argv[1], mmio.Field1, 100, 0, mmio.Field4); mmio.Mode = Z502StartContext; // Field1 contains the value of the context returned in the last call mmio.Field2 = START_NEW_CONTEXT_AND_SUSPEND; MEM_WRITE(Z502Context, &mmio); // Start up the context } if ((argc > 1) && (strcmp(argv[1], "test7") == 0)) { mmio.Mode = Z502InitializeContext; mmio.Field1 = 0; mmio.Field2 = (long) test7; mmio.Field3 = (long) PageTable; mmio.Field4 = 0; InitializePCDQ(15); InitTimerQueue(15); InitReadyQueue(15); InitDiskQueue(15); MEM_WRITE(Z502Context, &mmio); // Start of Make Context Sequence OSCreateProcess(argv[1], mmio.Field1, 100, 0, mmio.Field4); mmio.Mode = Z502StartContext; // Field1 contains the value of the context returned in the last call mmio.Field2 = START_NEW_CONTEXT_AND_SUSPEND; MEM_WRITE(Z502Context, &mmio); // Start up the context } if ((argc > 1) && (strcmp(argv[1], "test8") == 0)) { mmio.Mode = Z502InitializeContext; mmio.Field1 = 0; mmio.Field2 = (long) test8; mmio.Field3 = (long) PageTable; mmio.Field4 = 0; InitializePCDQ(15); InitTimerQueue(15); InitReadyQueue(15); InitDiskQueue(15); MEM_WRITE(Z502Context, &mmio); // Start of Make Context Sequence OSCreateProcess(argv[1], mmio.Field1, 100, 0, mmio.Field4); mmio.Mode = Z502StartContext; // Field1 contains the value of the context returned in the last call mmio.Field2 = START_NEW_CONTEXT_AND_SUSPEND; MEM_WRITE(Z502Context, &mmio); // Start up the context } } // End of osInit
void svc(SYSTEM_CALL_DATA *SystemCallData) { short call_type; static short do_print = 10; short i; INT32 Time; int Status; void *PageTable; char* processName; MEMORY_MAPPED_IO mmio; call_type = (short) SystemCallData->SystemCallNumber; if (do_print > 0) { printf("SVC handler: %s\n", call_names[call_type]); for (i = 0; i < SystemCallData->NumberOfArguments - 1; i++) { //Value = (long)*SystemCallData->Argument[i]; printf("Arg %d: Contents = (Decimal) %8ld, (Hex) %8lX\n", i, (unsigned long) SystemCallData->Argument[i], (unsigned long) SystemCallData->Argument[i]); } do_print--; } // printf((char *) SystemCallData->Argument[i]); switch (call_type) { //get time service call case SYSNUM_GET_TIME_OF_DAY: mmio.Mode = Z502ReturnValue; mmio.Field1 = mmio.Field2 = mmio.Field3 = 0; MEM_READ(Z502Clock, &mmio); *(long *) SystemCallData->Argument[0] = mmio.Field1; break; //system sleep call case SYSNUM_SLEEP: mmio.Mode = Z502ReturnValue; mmio.Field1 = mmio.Field2 = mmio.Field3 = 0; MEM_READ(Z502Clock, &mmio); Time = (long) SystemCallData->Argument[0]; pcb = FindCurrent(runningProcessPid); pcb->wakeUpTimer = Time; EnTimerQueue(&pcb_timer_queue, pcb); //start timer headPCB = GetHead(&pcb_timer_queue)->data; if (pcb == headPCB) { mmio.Mode = Z502Start; mmio.Field1 = (long) SystemCallData->Argument[0]; mmio.Field2 = mmio.Field3 = 0; MEM_WRITE(Z502Timer, &mmio); } Dispatcher(); break; //system create process case SYSNUM_CREATE_PROCESS: if ((long) SystemCallData->Argument[2] < 0) { *SystemCallData->Argument[4] = ERR_BAD_PARAM; } else { PageTable = (void *) calloc(2, NUMBER_VIRTUAL_PAGES); mmio.Mode = Z502InitializeContext; mmio.Field1 = 0; mmio.Field2 = (long) SystemCallData->Argument[1]; mmio.Field3 = (long) PageTable; MEM_WRITE(Z502Context, &mmio); pcb = OSCreateProcess((char*) SystemCallData->Argument[0], (long) mmio.Field1, (long) SystemCallData->Argument[2], (long) SystemCallData->Argument[3], (long) SystemCallData->Argument[4]); if (pcb != NULL) { EnQueue(&pcb_ready_queue, (void*) pcb); *SystemCallData->Argument[3] = pcb->pid; *SystemCallData->Argument[4] = ERR_SUCCESS; } else { *SystemCallData->Argument[4] = ERR_BAD_PARAM; } } break; //system get process id case SYSNUM_GET_PROCESS_ID: processName = (char*) SystemCallData->Argument[0]; if (strlen(processName) == 0) { *SystemCallData->Argument[1] = runningProcessPid; *SystemCallData->Argument[2] = ERR_SUCCESS; } else { pcb = FindPCBByName(processName); } if (pcb != NULL) { *SystemCallData->Argument[1] = pcb->pid; *SystemCallData->Argument[2] = ERR_SUCCESS; } else { *SystemCallData->Argument[2] = ERR_BAD_PARAM; } break; case SYSNUM_PHYSICAL_DISK_READ: do { mmio.Mode = Z502Status; mmio.Field1 = (long) SystemCallData->Argument[0]; mmio.Field2 = mmio.Field3 = 0; MEM_READ(Z502Disk, &mmio); CALL(WasteTime()); } while (mmio.Field2 != DEVICE_FREE); pcb = FindCurrent(runningProcessPid); if (pcb != NULL) { pcb->diskID = (int) SystemCallData->Argument[0]; pcb->sectorID = (int) SystemCallData->Argument[1]; pcb->memoryBuffer = (void*) SystemCallData->Argument[2]; EnQueue(&(pcb_disk_queue[pcb->diskID]), (void*) pcb); } mmio.Mode = Z502DiskRead; mmio.Field1 = (long) SystemCallData->Argument[0]; mmio.Field2 = (long) SystemCallData->Argument[1]; mmio.Field3 = (long) SystemCallData->Argument[2]; mmio.Field4 = 0; MEM_READ(Z502Disk, &mmio); do { mmio.Mode = Z502Status; mmio.Field1 = (long) SystemCallData->Argument[0]; mmio.Field2 = mmio.Field3 = 0; MEM_READ(Z502Disk, &mmio); CALL(WasteTime()); } while (mmio.Field2 != DEVICE_FREE); Dispatcher(); break; case SYSNUM_PHYSICAL_DISK_WRITE: do { mmio.Mode = Z502Status; mmio.Field1 = (long) SystemCallData->Argument[0]; mmio.Field2 = mmio.Field3 = 0; MEM_READ(Z502Disk, &mmio); CALL(WasteTime()); } while (mmio.Field2 != DEVICE_FREE); pcb = FindCurrent(runningProcessPid); if (pcb != NULL) { pcb->diskID = (int) SystemCallData->Argument[0]; pcb->sectorID = (int) SystemCallData->Argument[1]; pcb->memoryBuffer = (void*) SystemCallData->Argument[2]; EnQueue(&(pcb_disk_queue[pcb->diskID]), (void*) pcb); } mmio.Mode = Z502DiskWrite; mmio.Field1 = (long) SystemCallData->Argument[0]; mmio.Field2 = (long) SystemCallData->Argument[1]; mmio.Field3 = (long) SystemCallData->Argument[2]; MEM_WRITE(Z502Disk, &mmio); // mmio.Mode = Z502Action; // mmio.Field1 = mmio.Field2 = mmio.Field3 = 0; // MEM_WRITE(Z502Idle, &mmio); do { mmio.Mode = Z502Status; mmio.Field1 = (long) SystemCallData->Argument[0]; mmio.Field2 = mmio.Field3 = 0; MEM_READ(Z502Disk, &mmio); CALL(WasteTime()); } while (mmio.Field2 != DEVICE_FREE); Dispatcher(); break; //system terminate call case SYSNUM_TERMINATE_PROCESS: //If ProcessID = -1, then terminate self if ((long) SystemCallData->Argument[0] == -1) { pcb = FindCurrent(runningProcessPid); if (pcb != NULL) { // ReleasePCB(); // RemovePCB(&pcb_ready_queue,(void*)pcb); // RemovePCB(&pcb_timer_queue,(void*)pcb); // *SystemCallData->Argument[1] = ERR_SUCCESS; if (pcb_ready_queue.size == 0 && pcb_timer_queue.size == 0) { mmio.Mode = Z502ReturnValue; mmio.Field1 = mmio.Field2 = mmio.Field3 = mmio.Field4 = 0; MEM_WRITE(Z502Halt, &mmio); *SystemCallData->Argument[1] = ERR_SUCCESS; } else { Dispatcher(); } } else { ReleasePCB(); mmio.Mode = Z502ReturnValue; mmio.Field1 = mmio.Field2 = mmio.Field3 = mmio.Field4 = 0; MEM_WRITE(Z502Halt, &mmio); *SystemCallData->Argument[1] = ERR_SUCCESS; } } else if ((long) SystemCallData->Argument[0] == -2) { // terminite all halt ReleasePCB(); mmio.Mode = Z502ReturnValue; mmio.Field1 = mmio.Field2 = mmio.Field3 = mmio.Field4 = 0; MEM_WRITE(Z502Halt, &mmio); *SystemCallData->Argument[1] = ERR_SUCCESS; // pcb = FindCurrent(runningProcessPid); // RemovePCB(&pcb_ready_queue, (void*) pcb); // RemovePCB(&pcb_timer_queue, (void*) pcb); // RemovePCB(&pcb_ready_queue, (void*) pcb->childProcesses); // RemovePCB(&pcb_timer_queue, (void*) pcb->childProcesses); } else { pcb = FindPCBByPID(SystemCallData->Argument[0]); RemovePCB(&pcb_ready_queue, (void*) pcb); *SystemCallData->Argument[1] = ERR_SUCCESS; } break; defaut: printf("ERROR! call_type not recognized!\n"); printf("Call_type is %i\n", call_type); } } // End of svc
void osInit(int argc, char *argv[]) { void *PageTable = (void *) calloc(2, VIRTUAL_MEM_PAGES); INT32 i; MEMORY_MAPPED_IO mmio; //init Queues initPCBTable(); initTimerQueue(); initReadyQueue(); initMessageTable(); // Demonstrates how calling arguments are passed thru to here printf( "Program called with %d arguments:", argc ); for ( i = 0; i < argc; i++ ) printf( " %s", argv[i] ); printf( "\n" ); printf( "Calling with argument 'sample' executes the sample program.\n" ); // Here we check if a second argument is present on the command line. // If so, run in multiprocessor mode if ( argc > 2 ){ printf("Simulation is running as a MultProcessor\n\n"); mmio.Mode = Z502SetProcessorNumber; mmio.Field1 = MAX_NUMBER_OF_PROCESSORS; mmio.Field2 = (long) 0; mmio.Field3 = (long) 0; mmio.Field4 = (long) 0; MEM_WRITE(Z502Processor, &mmio); // Set the number of processors } else { printf("Simulation is running as a UniProcessor\n"); printf("Add an 'M' to the command line to invoke multiprocessor operation.\n\n"); } // Setup so handlers will come to code in base.c TO_VECTOR[TO_VECTOR_INT_HANDLER_ADDR ] = (void *) InterruptHandler; TO_VECTOR[TO_VECTOR_FAULT_HANDLER_ADDR ] = (void *) FaultHandler; TO_VECTOR[TO_VECTOR_TRAP_HANDLER_ADDR ] = (void *) svc; // Determine if the switch was set, and if so go to demo routine. PageTable = (void *) calloc(2, VIRTUAL_MEM_PAGES); if ((argc > 1) && (strcmp(argv[1], "sample") == 0)) { mmio.Mode = Z502InitializeContext; mmio.Field1 = 0; mmio.Field2 = (long) SampleCode; mmio.Field3 = (long) PageTable; MEM_WRITE(Z502Context, &mmio); // Start of Make Context Sequence mmio.Mode = Z502StartContext; // Field1 contains the value of the context returned in the last call mmio.Field2 = START_NEW_CONTEXT_AND_SUSPEND; MEM_WRITE(Z502Context, &mmio); // Start up the context } // End of handler for sample code - This routine should never return here /****************************Parse Input******************************/ long *TestToRun; switch (argc){ case 2: TestToRun = TestParser(argv[1]); ProcessorMode = Uniprocessor; break; case 3: TestToRun = TestParser(argv[1]); ProcessorMode = Multiprocessor; break; default: TestToRun = test1c; ProcessorMode = Uniprocessor; break; } /********************************************************************/ long ErrorReturned; long newPID; struct Process_Control_Block *newPCB = OSCreateProcess((long*)"test1", TestToRun, (long*)3, (long*)&newPID, (long*)&ErrorReturned); if (newPCB != NULL) { enPCBTable(newPCB); enReadyQueue(newPCB); } Dispatcher(); } // End of osInit
void svc(SYSTEM_CALL_DATA *SystemCallData) { short call_type; static short do_print = 10; short i; //for hardware interface MEMORY_MAPPED_IO mmio; //for GET_TIME_OF_DAY INT32 Temp_Clock; //for SLEEP long Sleep_Time; struct Process_Control_Block *sleepPCB; //for RESTART_PROCESS long PID_restart; struct Process_Control_Block *restartPCB; struct Process_Control_Block *recreatedPCB; //for CREATE_PROCESS struct Process_Control_Block *newPCB; //for TERMINATE_PROCESS long termPID; struct Process_Control_Block *termPCB; //for GET_PROCESS_ID int ReturnedPID; char* ProcessName; struct Process_Control_Block *PCBbyProcessName; //for SUSPEND_PROCESS int suspendPID; struct Process_Control_Block *suspendPCB; //for RESUME_PROCESS int resumePID; struct Process_Control_Block *resumePCB; //for CHANGE_PRIORITY int changePrioPID; struct Process_Control_Block *changePrioPCB; int newPriority; //for SEND_MESSAGE long TargetPID; char *MessageBuffer; long SendLength; struct Message *MessageCreated; long *ErrorReturned_SendMessage; //for RECEIVE_MESSAGE long SourcePID; char *ReceiveBuffer; long ReceiveLength; long *ActualSendLength; long *ActualSourcePID; long *ErrorReturned_ReceiveMessage; struct Process_Control_Block *Mess_PCB; call_type = (short) SystemCallData->SystemCallNumber; if (do_print > 0) { printf("SVC handler: %s\n", call_names[call_type]); for (i = 0; i < SystemCallData->NumberOfArguments - 1; i++) { //Value = (long)*SystemCallData->Argument[i]; printf("Arg %d: Contents = (Decimal) %8ld, (Hex) %8lX\n", i, (unsigned long) SystemCallData->Argument[i], (unsigned long) SystemCallData->Argument[i]); } do_print--; } switch (call_type) { //get and return current system time case SYSNUM_GET_TIME_OF_DAY: mmio.Mode = Z502ReturnValue; mmio.Field1 = mmio.Field2 = mmio.Field3 = 0; MEM_READ(Z502Clock, &mmio); Temp_Clock = mmio.Field1; *SystemCallData->Argument[0] = Temp_Clock; break; //create a new PCB and put it into pcb table and ready queue case SYSNUM_CREATE_PROCESS: //create a new PCB newPCB = OSCreateProcess(SystemCallData->Argument[0], SystemCallData->Argument[1], SystemCallData->Argument[2], SystemCallData->Argument[3], SystemCallData->Argument[4]); //if create successfully, put it into PCB table and ready queue if (newPCB != NULL) { SchedularPrinter("Create", newPCB->ProcessID);//print states enPCBTable(newPCB); enReadyQueue(newPCB); } break; //return PID regarding process name case SYSNUM_GET_PROCESS_ID: ProcessName = (char*)SystemCallData->Argument[0]; //if no input process name, return the current running PID if (strcmp(ProcessName, "") == 0) { PCBbyProcessName = CurrentPCB(); *SystemCallData->Argument[1] = PCBbyProcessName->ProcessID; *SystemCallData->Argument[2] = ERR_SUCCESS; } //find the PCB in PCB table and return PID if found else { PCBbyProcessName = findPCBbyProcessName(ProcessName); //if found, return PID if (PCBbyProcessName != NULL) { ReturnedPID = PCBbyProcessName->ProcessID; *SystemCallData->Argument[1] = ReturnedPID; *SystemCallData->Argument[2] = ERR_SUCCESS; } //if not found, return error else { *SystemCallData->Argument[2] = ERR_BAD_PARAM; } } break; //if a PCB wanna sleep, put itself into timer queue and start //a new PCB case SYSNUM_SLEEP: //print states SchedularPrinter("Sleep", CurrentPID()); //Calculate WakeUpTime for PCB Sleep_Time = (long)SystemCallData->Argument[0]; sleepPCB = CurrentPCB(); sleepPCB->WakeUpTime = CurrentTime() + Sleep_Time; //Put current running PCB into timer queue and reset time lockTimer(); enTimerQueue(sleepPCB); if (sleepPCB == timerQueue->First_Element->PCB){ SetTimer(Sleep_Time); } unlockTimer(); //in uniprocessor, start a new PCB //in multiprocessor, only suspend itself if (ProcessorMode == Uniprocessor) { //first PCB in Ready Queue starts Dispatcher(); } else { OSSuspendCurrentProcess(); } break; //restart a PCB by terminate itself and created a new PCB with everything the same except PID case SYSNUM_RESTART_PROCESS: //initial return error *SystemCallData->Argument[2] = ERR_BAD_PARAM; PID_restart = (long)SystemCallData->Argument[0]; //if not restart itself if (PID_restart != CurrentPID()){ //find restarted PCB restartPCB = findPCBbyProcessID(PID_restart); //if PCB found, terminate itself and create a new one if (restartPCB != NULL){ TerminateProcess(restartPCB); recreatedPCB = OSCreateProcess(restartPCB->ProcessName, restartPCB->TestToRun, restartPCB->Priority, SystemCallData->Argument[1], SystemCallData->Argument[2]); //if create successfully, put it into PCB table and ready queue if (recreatedPCB != NULL) { *SystemCallData->Argument[2] = ERR_SUCCESS; SchedularPrinter("Create", recreatedPCB->ProcessID);//print states enPCBTable(recreatedPCB); enReadyQueue(recreatedPCB); SchedularPrinter("Restart", restartPCB->ProcessID); } } else{ *SystemCallData->Argument[2] = ERR_BAD_PARAM; } } else{ *SystemCallData->Argument[2] = ERR_BAD_PARAM; } break; //terminate a process case SYSNUM_TERMINATE_PROCESS: termPID = (long)SystemCallData->Argument[0]; //if PID = -1, terminate current running PCB if (termPID == -1) { if (PCBLiveNumber() > 1) { *SystemCallData->Argument[1] = ERR_SUCCESS; //print states SchedularPrinter("Terminate", termPID); //terminate current PCB TerminateProcess(CurrentPCB()); } else { *SystemCallData->Argument[1] = ERR_SUCCESS; HaltProcess(); } } //if PID = -2, terminate OS if (termPID == -2) { *SystemCallData->Argument[1] = ERR_SUCCESS; HaltProcess(); } //if PID positive, terminate specified PID else { termPCB = findPCBbyProcessID((long)SystemCallData->Argument[0]); //if PCB found, terminate it if (termPCB != NULL) { *SystemCallData->Argument[1] = ERR_SUCCESS; //if more than one PCB alive, simply terminate it if (PCBLiveNumber() > 1) { //print states SchedularPrinter("Terminate", termPID); //terminate specified PCB TerminateProcess(termPCB); } //if last alive PCB, terminate OS else { HaltProcess(); } } else { *SystemCallData->Argument[1] = ERR_BAD_PARAM; } } break; //suspend a PCB, which can be resumed case SYSNUM_SUSPEND_PROCESS: suspendPID = (int)SystemCallData->Argument[0]; //if PID = -1, suspend current running PCB if (suspendPID == -1) { //if more than one PCB alive, suspend it if (PCBLiveNumber() > 1) { *SystemCallData->Argument[1] = ERR_SUCCESS; //print states SchedularPrinter("Suspend", suspendPID); //Suspend Current Process SuspendProcess(CurrentPCB()); } //if last one PCB alive, return error else { *SystemCallData->Argument[1] = ERR_BAD_PARAM; } } //if PID positive, suspend specified PCB else { suspendPCB = findPCBbyProcessID((int)suspendPID); //if PCB found if (suspendPCB != NULL) { //if more than one PCB alive, suspend it if (suspendPCB->ProcessState == PCB_STATE_LIVE && PCBLiveNumber() > 1) { *SystemCallData->Argument[1] = ERR_SUCCESS; //print states SchedularPrinter("Suspend", suspendPID); //Suspend specified process SuspendProcess(suspendPCB); } //if last one PCB alive, return error else { *SystemCallData->Argument[1] = ERR_BAD_PARAM; } } else { *SystemCallData->Argument[1] = ERR_BAD_PARAM; } } break; //resumes a previously suspended PCB case SYSNUM_RESUME_PROCESS: resumePID = (int)SystemCallData->Argument[0]; resumePCB = findPCBbyProcessID(resumePID); //if PCB found if (resumePCB != NULL) { //if PCB is previously suspended if (resumePCB->ProcessState == PCB_STATE_SUSPEND) { *SystemCallData->Argument[1] = ERR_SUCCESS; //print states SchedularPrinter("Resume", resumePID); //Resume specified process ResumeProcess(resumePCB); } else { *SystemCallData->Argument[1] = ERR_BAD_PARAM; } } else { *SystemCallData->Argument[1] = ERR_BAD_PARAM; } break; //change the priority of a PCB case SYSNUM_CHANGE_PRIORITY: changePrioPID = (int)SystemCallData->Argument[0]; changePrioPCB = findPCBbyProcessID((int)changePrioPID); newPriority = (int)SystemCallData->Argument[1]; //if legal priority if (newPriority<=40 && newPriority>=0) { if (changePrioPCB != NULL) { *SystemCallData->Argument[2] = ERR_SUCCESS; //print states printf("Before changing Priority\n"); SchedularPrinter("ChangePrio", changePrioPID); //if PCB in ready queue, change order in ready queue if (changePrioPCB->ProcessLocation == PCB_LOCATION_READY_QUEUE && newPriority != changePrioPCB->Priority) { changePrioPCB = deCertainPCBFromReadyQueue(changePrioPID); changePrioPCB->Priority = newPriority; enReadyQueue(changePrioPCB); } else { changePrioPCB->Priority = newPriority; } //print states printf("After changing Priority\n"); SchedularPrinter("ChangePrio", changePrioPID); } else { *SystemCallData->Argument[2] = ERR_BAD_PARAM; } } else { *SystemCallData->Argument[2] = ERR_BAD_PARAM; } break; //PCB stores a message in message table case SYSNUM_SEND_MESSAGE: TargetPID = (long)SystemCallData->Argument[0]; MessageBuffer = (char*)SystemCallData->Argument[1]; SendLength = (long)SystemCallData->Argument[2]; ErrorReturned_SendMessage = SystemCallData->Argument[3]; //create a message MessageCreated = CreateMessage(TargetPID, MessageBuffer, SendLength, ErrorReturned_SendMessage); //if successfully create a message, put it into message table if (MessageCreated != NULL) { SchedularPrinter("SendMsg", TargetPID); enMessageTable(MessageCreated); } break; //retrive a message in message table case SYSNUM_RECEIVE_MESSAGE: SourcePID = (long)SystemCallData->Argument[0]; ReceiveBuffer = (char*)SystemCallData->Argument[1]; ReceiveLength = (long)SystemCallData->Argument[2]; ActualSendLength = SystemCallData->Argument[3]; ActualSourcePID = SystemCallData->Argument[4]; ErrorReturned_ReceiveMessage = SystemCallData->Argument[5]; Mess_PCB = CurrentPCB(); Mess_PCB->ProcessState = PCB_STATE_MSG_SUSPEND; pcbTable->Msg_Suspended_Number += 1; //PCB kept suspended by sleep until find a message while (findMessage(SourcePID, ReceiveBuffer, ReceiveLength, ActualSendLength, ActualSourcePID, ErrorReturned_ReceiveMessage) == 0) { Mess_PCB->WakeUpTime = CurrentTime() + 10; //Put current running PCB into timer queue and reset time enTimerQueue(Mess_PCB); if (Mess_PCB == timerQueue->First_Element->PCB) { SetTimer(10); } //first PCB in Ready Queue starts Dispatcher(); } Mess_PCB->ProcessState = PCB_STATE_LIVE; pcbTable->Msg_Suspended_Number -= 1; SchedularPrinter("ReceiveMsg", CurrentPID()); break; default: printf("ERROR! call_type not recognized!\n"); printf("Call_type is - %i\n", call_type); } } // End of svc
void osInit(int argc, char *argv[]) { INT32 i; MEMORY_MAPPED_IO mmio; long a; long b; long* arg0=(long*)"test2a"; //default ruuning test long* arg1=(long*)test2a; long* arg2=(long*)10; long* arg3=& a; long* arg4=& b; // Demonstrates how calling arguments are passed thru to here printf( "Program called with %d arguments:", argc ); for ( i = 0; i < argc; i++ ) printf( " %s", argv[i] ); printf( "\n" ); printf( "Calling with argument 'sample' executes the sample program.\n" ); // Here we check if a second argument is present on the command line. // If so, run in multiprocessor mode if ( argc > 2 ){ printf("Simulation is running as a MultProcessor\n\n"); mmio.Mode = Z502SetProcessorNumber; mmio.Field1 = MAX_NUMBER_OF_PROCESSORS; mmio.Field2 = (long) 0; mmio.Field3 = (long) 0; mmio.Field4 = (long) 0; MEM_WRITE(Z502Processor, &mmio); // Set the number of processors } else { printf("Simulation is running as a UniProcessor\n"); printf("Add an 'M' to the command line to invoke multiprocessor operation.\n\n"); } // Setup so handlers will come to code in base.c TO_VECTOR[TO_VECTOR_INT_HANDLER_ADDR ] = (void *) InterruptHandler; TO_VECTOR[TO_VECTOR_FAULT_HANDLER_ADDR ] = (void *) FaultHandler; TO_VECTOR[TO_VECTOR_TRAP_HANDLER_ADDR ] = (void *) svc; if((argc > 1) && (strcmp(argv[1], "test1a") == 0)){ arg0=(long*)"test1a"; arg1=(long*)test1a; OSCreateProcess(arg0,arg1,arg2,arg3,arg4); Dispatcher(); } if((argc > 1) && (strcmp(argv[1], "test1b") == 0)){ arg0=(long*)"test1b"; arg1=(long*)test1b; OSCreateProcess(arg0,arg1,arg2,arg3,arg4); Dispatcher(); } if((argc > 1) && (strcmp(argv[1], "test1c") == 0)){ arg0=(long*)"test1c"; arg1=(long*)test1c; OSCreateProcess(arg0,arg1,arg2,arg3,arg4); Dispatcher(); } if((argc > 1) && (strcmp(argv[1], "test1d") == 0)){ arg0=(long*)"test1d"; arg1=(long*)test1d; OSCreateProcess(arg0,arg1,arg2,arg3,arg4); Dispatcher(); } if((argc > 1) && (strcmp(argv[1], "test1e") == 0)){ arg0=(long*)"test1e"; arg1=(long*)test1e; OSCreateProcess(arg0,arg1,arg2,arg3,arg4); Dispatcher(); } if((argc > 1) && (strcmp(argv[1], "test1f") == 0)){ arg0=(long*)"test1f"; arg1=(long*)test1f; OSCreateProcess(arg0,arg1,arg2,arg3,arg4); Dispatcher(); } if((argc > 1) && (strcmp(argv[1], "test1g") == 0)){ arg0=(long*)"test1g"; arg1=(long*)test1g; OSCreateProcess(arg0,arg1,arg2,arg3,arg4); Dispatcher(); } if((argc > 1) && (strcmp(argv[1], "test1h") == 0)){ arg0=(long*)"test1h"; arg1=(long*)test1h; OSCreateProcess(arg0,arg1,arg2,arg3,arg4); Dispatcher(); } if((argc > 1) && (strcmp(argv[1], "test1i") == 0)){ arg0=(long*)"test1i"; arg1=(long*)test1i; OSCreateProcess(arg0,arg1,arg2,arg3,arg4); Dispatcher(); } if((argc > 1) && (strcmp(argv[1], "test1j") == 0)){ arg0=(long*)"test1j"; arg1=(long*)test1j; OSCreateProcess(arg0,arg1,arg2,arg3,arg4); Dispatcher(); } if((argc > 1) && (strcmp(argv[1], "test1k") == 0)){ arg0=(long*)"test1k"; arg1=(long*)test1k; OSCreateProcess(arg0,arg1,arg2,arg3,arg4); Dispatcher(); } /*project2*/ if((argc > 1) && (strcmp(argv[1], "test2a") == 0)){ arg0=(long*)"test2a"; arg1=(long*)test2a; OSCreateProcess(arg0,arg1,arg2,arg3,arg4); Dispatcher(); } if((argc > 1) && (strcmp(argv[1], "test2b") == 0)){ arg0=(long*)"test2b"; arg1=(long*)test2b; OSCreateProcess(arg0,arg1,arg2,arg3,arg4); Dispatcher(); } if((argc > 1) && (strcmp(argv[1], "test2c") == 0)){ arg0=(long*)"test2c"; arg1=(long*)test2c; OSCreateProcess(arg0,arg1,arg2,arg3,arg4); Dispatcher(); } if((argc > 1) && (strcmp(argv[1], "test2d") == 0)){ arg0=(long*)"test2d"; arg1=(long*)test2d; OSCreateProcess(arg0,arg1,arg2,arg3,arg4); Dispatcher(); } if((argc > 1) && (strcmp(argv[1], "test2e") == 0)){ arg0=(long*)"test2e"; arg1=(long*)test2e; OSCreateProcess(arg0,arg1,arg2,arg3,arg4); Dispatcher(); } if((argc > 1) && (strcmp(argv[1], "test2f") == 0)){ arg0=(long*)"test2f"; arg1=(long*)test2f; OSCreateProcess(arg0,arg1,arg2,arg3,arg4); Dispatcher(); } if((argc > 1) && (strcmp(argv[1], "test2g") == 0)){ arg0=(long*)"test2g"; arg1=(long*)test2g; OSCreateProcess(arg0,arg1,arg2,arg3,arg4); Dispatcher(); } if((argc > 1) && (strcmp(argv[1], "test2h") == 0)){ arg0=(long*)"test2h"; arg1=(long*)test2h; OSCreateProcess(arg0,arg1,arg2,arg3,arg4); Dispatcher(); } else{ OSCreateProcess(arg0,arg1,arg2,arg3,arg4); Dispatcher(); } } // End of osInit
void svc(SYSTEM_CALL_DATA *SystemCallData) { MEMORY_MAPPED_IO mmio; short call_type; static short do_print = 10; INT32 Time; INT32 Status; short i; long* arg0=SystemCallData->Argument[0]; long* arg1=SystemCallData->Argument[1]; long* arg2=SystemCallData->Argument[2]; long* arg3=SystemCallData->Argument[3]; long* arg4=SystemCallData->Argument[4]; long *arg5=SystemCallData->Argument[5]; call_type = (short) SystemCallData->SystemCallNumber; if (do_print > 0) { printf("SVC handler: %s\n", call_names[call_type]); for (i = 0; i < SystemCallData->NumberOfArguments - 1; i++) { printf("Arg %d: Contents = (Decimal) %8ld, (Hex) %8lX\n", i, (unsigned long) SystemCallData->Argument[i], (unsigned long) SystemCallData->Argument[i]); } do_print--; } switch (call_type) { // Get time service call case SYSNUM_GET_TIME_OF_DAY: mmio.Mode = Z502ReturnValue; mmio.Field1 = mmio.Field2 = mmio.Field3 = 0; MEM_READ(Z502Clock, &mmio);//hardware call Time = mmio.Field1; (SystemCallData->Argument[0])=(long*)&Time; //statePrinter(call_type,arg0, arg1, arg2, arg3, arg4); break; // get the Timer start and generate idle. case SYSNUM_SLEEP: startTimer(arg0); //statePrinter(call_type,arg0, arg1, arg2, arg3, arg4); Dispatcher();//call dispatcher break; // create process case SYSNUM_CREATE_PROCESS: OSCreateProcess(arg0,arg1,arg2,arg3,arg4); //statePrinter(call_type,arg0, arg1, arg2, arg3, arg4); break; // get process id case SYSNUM_GET_PROCESS_ID: getProcessID(arg0,arg1,arg2); //statePrinter(call_type,arg0, arg1, arg2, arg3, arg4); break; // suspend process case SYSNUM_SUSPEND_PROCESS: suspendProcess(arg0, arg1); //statePrinter(call_type,arg0, arg1, arg2, arg3, arg4); break; // resume the process case SYSNUM_RESUME_PROCESS: resumeProcess(arg0, arg1); //statePrinter(call_type,arg0, arg1, arg2, arg3, arg4); break; // change priority; case SYSNUM_CHANGE_PRIORITY: changePriority(arg0,arg1,arg2); //statePrinter(call_type,arg0, arg1, arg2, arg3, arg4); break; // terminate system call case SYSNUM_TERMINATE_PROCESS: terminateSysProcess(arg0,arg1); break; case SYSNUM_SEND_MESSAGE: Send_message(arg0, arg1, arg2, arg3); break; case SYSNUM_RECEIVE_MESSAGE: ReceiveMessage(arg0, arg1, arg2, arg3, arg4, arg5); break; case SYSNUM_DISK_WRITE: DiskWrite(arg0, arg1, arg2); break; case SYSNUM_DISK_READ: DiskRead(arg0, arg1, arg2); break; case SYSNUM_DEFINE_SHARED_AREA: DefineSharedArea(arg0, arg1, arg2,arg3,arg4); break; default: printf( "ERROR! call_type not recognized!\n" ); printf( "Call_type is - %i\n", call_type); } } // End of svc