Exemple #1
0
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;
}
Exemple #2
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
Exemple #3
0
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
Exemple #4
0
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
Exemple #5
0
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
Exemple #6
0
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
Exemple #7
0
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