Example #1
0
void start_timer( int delaytime ) {

    int                 Status;
    PCB                 *head;
    Temp = delaytime;
    //MEM_READ( Z502TimerStatus, &Status);
    //READ_MODIFY(MEMORY_INTERLOCK_BASE, DO_LOCK, SUSPEND_UNTIL_LOCKED,&LockResult);
    if(Running == NULL) {
        dispatcher();
        Z502SwitchContext( SWITCH_CONTEXT_SAVE_MODE, &(Running->context) );
    }

    MEM_READ(Z502ClockStatus, &Time);
    MEM_WRITE( Z502TimerStart, &Temp);
    Running->wakeuptime = Time+Temp;
    add_to_timerQ();
    dispatcher();

    //READ_MODIFY(MEMORY_INTERLOCK_BASE, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,&LockResult);

    if(Running == NULL)
    {
        CALL(Z502Idle());
    }
    //Z502Idle();


}
Example #2
0
//This function reset timer according to first PCB in timer queue
int ResetTimer(){
	MEMORY_MAPPED_IO mmio;    //for hardware interface
	int SleepTime;

	//when timer queue is not empty
	if (timerQueue->Element_Number > 0){
		//calculate sleep time
		SleepTime = timerQueue->First_Element->PCB->WakeUpTime - CurrentTime();
		//set timer only if it's positive
		if (SleepTime > 0){
			mmio.Mode = Z502Start;
			mmio.Field1 = SleepTime;   // You pick the time units
			mmio.Field2 = mmio.Field3 = 0;
			MEM_WRITE(Z502Timer, &mmio);
			//if success, return 1
			return 1;
		}
		else{
			//if sleep time is negative, return 0
			return 0;
		}
	}
	else{
		//if timer queue empty, return -1
		return -1;
	}
}
Example #3
0
File: base.c Project: zhshr/CS502
void FaultHandler(void) {
	INT32 DeviceID;
	INT32 Status;
	MEMORY_MAPPED_IO mmio;       // Enables communication with hardware

	// Get cause of interrupt
	mmio.Mode = Z502GetInterruptInfo;
	MEM_READ(Z502InterruptDevice, &mmio);
	DeviceID = mmio.Field1;
	Status = mmio.Field2;
	if (PrintFAUCount>0){
		printf("Fault_handler: Found vector type %d with value %d\n", DeviceID,
					Status);
		PrintFAUCount--;
	}

	if (DeviceID == PRIVILEGED_INSTRUCTION){
		debug(RED, "PRIVILEGED INSTRUCTION");
		//my_Halt();
	}
	if (DeviceID == INVALID_MEMORY){
		debug(RED, "Memory Fault on page %d", Status);
		my_AllocateNewPage(Status);
	}
	// Clear out this device - we're done with it
	mmio.Mode = Z502ClearInterruptStatus;
	mmio.Field1 = DeviceID;
	MEM_WRITE(Z502InterruptDevice, &mmio);
	//my_Dispatcher();
} // End of FaultHandler
Example #4
0
void Dispatcher(){
	MEMORY_MAPPED_IO mmio;
	struct ready_PCB *runningPCB;
	int runnningPID;

//	runningPcb = FindCurrent(runningProcessPid);

	runningPCB=Get_R_Head();
	while(runningPCB==NULL) {

//		if(GetHead(&pcb_timer_queue)!= NULL || GetHead(&pcb_disk_queue!=NULL)) {
//			mmio.Mode=Z502Action;
//			mmio.Field1=mmio.Field2=mmio.Field3=0;
//			MEM_WRITE(Z502Idle, &mmio);
//
//		}
		CALL(WasteTime());
	}
	//pcb not null, start PCB if pcb is null call idle

	    runnningPID = runningPCB->pid;
	    Queue_R_Dequeue();

		mmio.Mode = Z502StartContext;
		mmio.Field1 =runningPCB->context.Field1;
		mmio.Field2 = START_NEW_CONTEXT_AND_SUSPEND;
		MEM_WRITE(Z502Context, &mmio);


}
Example #5
0
/************************************************************************
 INTERRUPT_HANDLER
 When the Z502 gets a hardware interrupt, it transfers control to
 this routine in the OS.
 ************************************************************************/
void InterruptHandler(void) {
	INT32 DeviceID;
//	INT32 Status;

	MEMORY_MAPPED_IO mmio;       // Enables communication with hardware

	static BOOL remove_this_in_your_code = TRUE; /** TEMP **/
	static INT32 how_many_interrupt_entries = 0; /** TEMP **/

	// Get cause of interrupt
	mmio.Mode = Z502GetInterruptInfo;
	mmio.Field1 = mmio.Field2 = mmio.Field3 = 0;
	MEM_READ(Z502InterruptDevice, &mmio);
	DeviceID = mmio.Field1;
	//Status = mmio.Field2;

/////////////////////////Code go here////////////////////////////////////

	//take all timeout PCB from timer queue and put into ready queue
	struct Process_Control_Block *tmpPCB;

	do{
		tmpPCB = deTimerQueue();
		enReadyQueue(tmpPCB);
	} while (ResetTimer() == 0);

/////////////////////////Code end here///////////////////////////////////
	
	// Clear out this device - we're done with it
	mmio.Mode = Z502ClearInterruptStatus;
	mmio.Field1 = DeviceID;
	mmio.Field2 = mmio.Field3 = 0;
	MEM_WRITE(Z502InterruptDevice, &mmio);
}           // End of InterruptHandler
Example #6
0
void FaultHandler(void) {
	INT32 DeviceID;
	INT32 Status;

	MEMORY_MAPPED_IO mmio;       // Enables communication with hardware

	// Get cause of interrupt
	mmio.Mode = Z502GetInterruptInfo;
	MEM_READ(Z502InterruptDevice, &mmio);
	DeviceID = mmio.Field1;
	Status = mmio.Field2;

	printf("Fault_handler: Found vector type %d with value %d\n", DeviceID,
			Status);
	/*****************************My Code******************************/
	//temperary code for test1k
	HaltProcess();
	
	/******************************************************************/

	// Clear out this device - we're done with it
	mmio.Mode = Z502ClearInterruptStatus;
	mmio.Field1 = DeviceID;
	MEM_WRITE(Z502InterruptDevice, &mmio);
} // End of FaultHandler
Example #7
0
int Terminate_Process(PCB *pcb, int child){
	if (child==TRUE){
		//terminate self and all children
		INT32 pid = pcb->PID;
		PCBListItem *temp = pcbHead;
		while(temp->Next!=NULL){
			if ((temp->Next->PCB->parentPID == pid)&&(temp->Next->PCB->status != PROCESS_Terminated)){
				Terminate_Process(temp->Next->PCB, TRUE);
			}
			temp = temp->Next;
		}
	}
	debug(YELLOW, "Terminating Process %d, parent PID %d", pcb->PID, pcb->parentPID);
	//(After terminated all children) terminate self
	if (pcb->parentPID == -1){
		//This is the test process, terminate it will cause simulation to stop
		MEMORY_MAPPED_IO mmio;
		mmio.Mode = Z502Action;
		MEM_WRITE(Z502Halt, &mmio);
	}
	ReadyQueue_Remove(pcb->PID);
	TimerQueue_Remove(pcb->PID);
	Printer("Terminate", pcb->PID, FALSE);
	if (pcb->status == PROCESS_RUNNING){
		pcb->status = PROCESS_Terminated;
		processCount--;
		return TRUE;
	}else{
		pcb->status = PROCESS_Terminated;
		processCount--;
		return FALSE;
	}

}
Example #8
0
//In uniprocessor mode
//This function starts a PCB and suspend others
void OSStartProcess(struct Process_Control_Block* PCB){
	MEMORY_MAPPED_IO mmio;

	mmio.Mode = Z502StartContext;
	mmio.Field1 = PCB->ContextID;
	mmio.Field2 = START_NEW_CONTEXT_AND_SUSPEND;
	MEM_WRITE(Z502Context, &mmio);     // Start up the context
}
Example #9
0
void test2e(void)
{
    int Iterations;

    GET_PROCESS_ID("", &Z502_REG4, &Z502_REG9);
    printf("\n\nRelease %s:Test 2e: Pid %ld\n", CURRENT_REL, Z502_REG4);

    for (Iterations = 0; Iterations < VIRTUAL_MEM_PGS; Iterations +=
            STEP_SIZE)
    {
        Z502_REG3 = PGSIZE * Iterations; // Generate address
        Z502_REG1 = Z502_REG3 + Z502_REG4; // Generate data 
        MEM_WRITE(Z502_REG3, &Z502_REG1); // Write the data

        MEM_READ(Z502_REG3, &Z502_REG2); // Read back data

        if (Iterations % DISPLAY_GRANULARITY2e == 0)
            printf("PID= %ld  address= %ld   written= %ld   read= %ld\n",
                   Z502_REG4, Z502_REG3, Z502_REG1, Z502_REG2);
        if (Z502_REG2 != Z502_REG1) // Written = read?
            printf("AN ERROR HAS OCCURRED.\n");

        // It makes life more fun!! to write the data again
        MEM_WRITE(Z502_REG3, &Z502_REG1); // Write the data

    } // End of for loop

    // Now read back the data we've written and paged
    printf("Reading back data: test 2e, PID %ld.\n", Z502_REG4);
    for (Iterations = 0; Iterations < VIRTUAL_MEM_PGS; Iterations +=
            STEP_SIZE)
    {

        Z502_REG3 = PGSIZE * Iterations; // Generate address
        Z502_REG1 = Z502_REG3 + Z502_REG4; // Data expected
        MEM_READ(Z502_REG3, &Z502_REG2); // Read back data

        if (Iterations % DISPLAY_GRANULARITY2e == 0)
            printf("PID= %ld  address= %ld   written= %ld   read= %ld\n",
                   Z502_REG4, Z502_REG3, Z502_REG1, Z502_REG2);
        if (Z502_REG2 != Z502_REG1) // Written = read?
            printf("AN ERROR HAS OCCURRED.\n");

    } // End of for loop
    TERMINATE_PROCESS(-2, &Z502_REG5); // Added 12/1/2013
} // End of test2e    
Example #10
0
File: base.c Project: ShunYao/OS502
void    fault_handler( void )
    {
    INT32       device_id;
    INT32       status;
    INT32       Index = 0;

    // Get cause of interrupt
    MEM_READ(Z502InterruptDevice, &device_id );
    // Set this device as target of our query
    MEM_WRITE(Z502InterruptDevice, &device_id );
    // Now read the status of this device
    MEM_READ(Z502InterruptStatus, &status );

    printf( "Fault_handler: Found vector type %d with value %d\n",
                        device_id, status );
    // Clear out this device - we're done with it
    MEM_WRITE(Z502InterruptClear, &Index );
}                                       /* End of fault_handler */
Example #11
0
JNIEXPORT void JNICALL
Java_go_Seq_writeByteArray(JNIEnv *env, jobject obj, jbyteArray v) {
	// For Byte array, we pass only the (array length, pointer) pair
	// encoded as two int64 values. If the array length is 0,
	// the pointer value is omitted.
	if (v == NULL) {
		MEM_WRITE(int64_t) = 0;
		return;
	}

	jsize len = (*env)->GetArrayLength(env, v);
	MEM_WRITE(int64_t) = len;
	if (len == 0) {
		return;
	}

	jbyte* b = pin_array(env, obj, v);
	MEM_WRITE(int64_t) = (jlong)(uintptr_t)b;
}
Example #12
0
File: base.c Project: ShunYao/OS502
void   start_timer(INT32 timer_time)
{	INT32          Time;
    INT32          SleepTime;

	CALL(MEM_READ( Z502ClockStatus, &Time ));
	
	CALL(MEM_WRITE( Z502TimerStart, &timer_time));
	TimerStatusTime = Time+timer_time;

}	
Example #13
0
//This function set the timer to specified value
void SetTimer(long SleepTime){
	MEMORY_MAPPED_IO mmio;    //for hardware interface
	//only set timer when sleep time is positive
	if (SleepTime > 0){
		mmio.Mode = Z502Start;
		mmio.Field1 = SleepTime;   // You pick the time units
		mmio.Field2 = mmio.Field3 = 0;
		MEM_WRITE(Z502Timer, &mmio);
	}
}
Example #14
0
//In multiprocessor mode
//This function is used to suspend current running PCB
void OSSuspendCurrentProcess() {
	MEMORY_MAPPED_IO mmio;
	pcbTable->Cur_Running_Number -= 1;
	struct Process_Control_Block* PCB = CurrentPCB();
	//set PCB state
	PCB->ProcessState = PCB_STATE_LIVE;

	mmio.Mode = Z502StartContext;
	mmio.Field1 = 0;
	mmio.Field2 = SUSPEND_CURRENT_CONTEXT_ONLY;
	MEM_WRITE(Z502Context, &mmio);     // Start up the context
}
Example #15
0
//Interface of CREATE_PROCESS system call
void my_CREATE_PROCESS(SYSTEM_CALL_DATA *SystemCallData, int multicore){
	//try to detect errors
	debug(BLUE, "Trying to Create Process: %s, Priority: %ld", SystemCallData->Argument[0], SystemCallData->Argument[2]);
	if (processCount>=MAX_PROCESS){
		*(INT32 *)SystemCallData->Argument[4] = ERR_MAX_PROCESS;
		debug(RED, "MAX PROCESS reached");
		return;
	}
	if (PCB_Get_By_Name((char*)SystemCallData->Argument[0])!=NULL){
		*(INT32 *)SystemCallData->Argument[4] = 1;
		debug(RED, "Error in CREATEPROCESS: Process name duplicate");
		return;
	}
	if ((INT32)(SystemCallData->Argument[2])<0l){
		*(INT32 *)SystemCallData->Argument[4] = 1;
		debug(RED, "Error in CREATEPROCESS: Priority Invalid");
		return;
	}
	PCB *newPCB = (PCB*)calloc(1, sizeof(PCB));
	newPCB->name = (char*)calloc(strlen((char*)SystemCallData->Argument[0]), sizeof(char));
	strcpy(newPCB->name, (char*)SystemCallData->Argument[0]);
	MEMORY_MAPPED_IO mmio;
	void* PageTable = (void*)calloc(2, VIRTUAL_MEM_PAGES);
	newPCB->PageTable = PageTable;
	mmio.Mode = Z502InitializeContext;
	mmio.Field1 = 0;
	mmio.Field2 = (long) SystemCallData->Argument[1];
	mmio.Field3 = (long) PageTable;
	MEM_WRITE(Z502Context, &mmio);   // Start of Make Context Sequence

	if (mmio.Field4!=ERR_SUCCESS){
		debug(RED, "Create Process Failed, Error Code: %ld",mmio.Field4);
		*(INT32 *)SystemCallData->Argument[4] = 1;
		return;
	}

	//Set up process control block
	newPCB->PID = currentPID++;
	newPCB->ContextId = mmio.Field1;
	newPCB->priority = SystemCallData->Argument[2];
	newPCB->status = PROCESS_READY;

	PCBList_Add(newPCB);
	ReadyQueue_Lock("Create Process");
	ReadyQueue_Add(newPCB);
	Printer("Create", newPCB->PID, FALSE);
	ReadyQueue_Unlock("Create Process");

	processCount++;
	debug(GREEN, "Process Created, PID: %d, context id: %ld", newPCB->PID, newPCB->ContextId);
	*SystemCallData->Argument[3] = newPCB->PID;
	*SystemCallData->Argument[4] = ERR_SUCCESS;
}
Example #16
0
//In multiprocessor mode
//This function is used to start a new PCB without suspending others
void OSStartProcess_Only(struct Process_Control_Block* PCB) {
	if (PCB->ProcessState != PCB_STATE_RUNNING) {
		MEMORY_MAPPED_IO mmio;
		pcbTable->Cur_Running_Number += 1;
		//set PCB state
		PCB->ProcessState = PCB_STATE_RUNNING;

		mmio.Mode = Z502StartContext;
		mmio.Field1 = PCB->ContextID;
		mmio.Field2 = START_NEW_CONTEXT_ONLY;
		MEM_WRITE(Z502Context, &mmio);     // Start up the context
	}
}
Example #17
0
File: Utils.c Project: zhshr/CS502
void setTimer(INT32 duration) {
	MEMORY_MAPPED_IO mmio;
	mmio.Mode = Z502Start;
	mmio.Field1 = duration;
	mmio.Field2 = mmio.Field3 = mmio.Field4 = 0;
	MEM_WRITE(Z502Timer, &mmio);
	debug(GREY, "Set timer duration %d, currentTimer is %d", duration,
			currentTimer);
	if (mmio.Field4 != ERR_SUCCESS) {
		debug(RED, "Timer Set failed %d %d %d", my_GET_TIME_OF_DAY(),
				mmio.Field2, mmio.Field4);
	}
}
Example #18
0
void Start_Context(PCB* pcb){
	MEMORY_MAPPED_IO mmio;
	mmio.Mode = Z502StartContext;
	mmio.Field1 = pcb->ContextId;
	debug(GREY, "Try to start context PID %d ContextID: %ld", pcb->PID, mmio.Field1);
	mmio.Field2 = (multicore?START_NEW_CONTEXT_ONLY:START_NEW_CONTEXT_AND_SUSPEND);

	MEM_WRITE(Z502Context, &mmio);
	if (mmio.Field4!=ERR_SUCCESS){
		debug(RED, "Try to start context PID %d FAILED", pcb->PID);
	}else{
		debug(BLUE, "Try to start context PID %d SUCCESS %d", pcb->PID, mmio.Field2);
	}
}
Example #19
0
File: base.c Project: ShunYao/OS502
/************************************************************************
    INTERRUPT_HANDLER
        When the Z502 gets a hardware interrupt, it transfers control to
        this routine in the OS.
************************************************************************/
void    interrupt_handler( void ) {
    INT32              device_id;
    INT32              status;
	INT32			   Time;
    INT32              Index = 0;
    static BOOL        remove_this_in_your_code = TRUE;   /** TEMP **/
    static INT32       how_many_interrupt_entries = 0;    /** TEMP **/
    // Get cause of interrupt
    MEM_READ(Z502InterruptDevice, &device_id );
    // Set this device as target of our query
    MEM_WRITE(Z502InterruptDevice, &device_id );
    // Now read the status of this device
    MEM_READ(Z502InterruptStatus, &status );
	
	switch(device_id)
	{
			case TIMER_ITR:
			CALL(MEM_READ(Z502ClockStatus, &Time));
			while(timerHead!=NULL)
			{
				if(Time>(timerHead->p_time))	
				{	
					printf("Interrupt_handler: Found device ID %d\n",timerHead->p_id);
					lockTimer();
					//overTimeModify();
					makeTimerToReady(timerHead);
					addToReadyQ(makeTimer);
					unlockTimer();
				}
			
			    else
				break;
			}
			break;
	}
    MEM_WRITE(Z502InterruptClear, &Index );
}                                       /* End of interrupt_handler */
Example #20
0
void test2b(void)
{
    static INT32 test_data[TEST_DATA_SIZE ] = {0, 4, PGSIZE - 2, PGSIZE, 3
        * PGSIZE - 2, (VIRTUAL_MEM_PGS - 1) * PGSIZE, VIRTUAL_MEM_PGS
        * PGSIZE - 2};

    GET_PROCESS_ID("", &Z502_REG4, &Z502_REG9);
    printf("\n\nRelease %s:Test 2b: Pid %ld\n", CURRENT_REL, Z502_REG4);

    Z502_REG8 = 5 * PGSIZE;
    Z502_REG6 = Z502_REG8 + Z502_REG4 + 7;
    MEM_WRITE(Z502_REG8, &Z502_REG6);

    // Loop through all the memory addresses defined
    while (TRUE)
    {
        Z502_REG3 = test_data[(INT16) Z502_REG5];
        Z502_REG1 = Z502_REG3 + Z502_REG4 + 27;
        MEM_WRITE(Z502_REG3, &Z502_REG1);

        MEM_READ(Z502_REG3, &Z502_REG2);

        printf("PID= %ld  address= %ld  written= %ld   read= %ld\n", Z502_REG4,
               Z502_REG3, Z502_REG1, Z502_REG2);
        if (Z502_REG2 != Z502_REG1)
            printf("AN ERROR HAS OCCURRED.\n");

        //      Go back and check earlier write
        MEM_READ(Z502_REG8, &Z502_REG7);

        printf("PID= %ld  address= %ld   written= %ld   read= %ld\n",
               Z502_REG4, Z502_REG8, Z502_REG6, Z502_REG7);
        if (Z502_REG6 != Z502_REG7)
            printf("AN ERROR HAS OCCURRED.\n");
        Z502_REG5++;
    }
} // End of test2b    
Example #21
0
/************************************************************************
    INTERRUPT_HANDLER
        When the Z502 gets a hardware interrupt, it transfers control to
        this routine in the OS. 
************************************************************************/
void    interrupt_handler( void ) {
    INT32              device_id;
    INT32              status;
    INT32              Index = 0;
    static BOOL        remove_this_in_your_code = TRUE;   /** TEMP **/
    static INT32       how_many_interrupt_entries = 0;    /** TEMP **/

    // Get cause of interrupt
    MEM_READ(Z502InterruptDevice, &device_id ); 
    // Set this device as target of our query
    MEM_WRITE(Z502InterruptDevice, &device_id );
    // Now read the status of this device
    MEM_READ(Z502InterruptStatus, &status );

    /** REMOVE THE NEXT SIX LINES **/
    how_many_interrupt_entries++;                         /** TEMP **/
    if ( remove_this_in_your_code && ( how_many_interrupt_entries < 20 ) )
        {
        printf( "Interrupt_handler: Found device ID %d with status %d\n", 
                        device_id, status );
    }
    // Clear out this device - we're done with it
    MEM_WRITE(Z502InterruptClear, &Index );
}                                       /* End of interrupt_handler */
Example #22
0
/************************************************************************
    INTERRUPT_HANDLER
        When the Z502 gets a hardware interrupt, it transfers control to
        this routine in the OS.
************************************************************************/
void    interrupt_handler( void ) {
    INT32              device_id;
    INT32              status;
    INT32              Index = 0;

    // Get cause of interrupt
    MEM_READ(Z502InterruptDevice, &device_id );
    // Set this device as target of our query
    MEM_WRITE(Z502InterruptDevice, &device_id );
    // Now read the status of this device
    MEM_READ(Z502InterruptStatus, &status );

    switch( device_id )
    {
    case 4:
        IHTimerInterrupt();
        break;

    case 5:  // disk 1
    case 6:  // disk 2
    case 7:  // disk 3
    case 8:  // disk 4
    case 9:  // disk 5
    case 10: // disk 6
    case 11: // disk 7
    case 12: // disk 8
        IHDiskInterrupt(device_id);
        break;

    default:
        break;
    }

    // Clear out this device - we're done with it
    MEM_WRITE(Z502InterruptClear, &Index );
}                                       /* End of interrupt_handler */
Example #23
0
//This function creates and returns a PCB
struct Process_Control_Block *OSCreateProcess(long *ProcessName, long *Test_To_Run, 
							long *Priority, long *ProcessID, long *ErrorReturned){
	//check input
	//if bad inputs checked, return NULL and error
	if ((int)Priority < 0){
		*ErrorReturned = ERR_BAD_PARAM;
		return NULL;
	}
	else if (findPCBbyProcessName((char*)ProcessName) != NULL){
		*ErrorReturned = ERR_BAD_PARAM;
		return NULL;
	}
	else if (pcbTable->Element_Number >= MAX_PCB_NUMBER){
		*ErrorReturned = ERR_BAD_PARAM;
		return NULL;
	}
	else{
		*ErrorReturned = ERR_SUCCESS;
	}

	void *PageTable = (void *)calloc(2, VIRTUAL_MEM_PAGES);
	MEMORY_MAPPED_IO mmio;
	//create a new PCB and allocate memory
	struct Process_Control_Block *newPCB = (struct Process_Control_Block*)malloc(sizeof(struct Process_Control_Block));

	//make context
	mmio.Mode = Z502InitializeContext;
	mmio.Field1 = 0;
	mmio.Field2 = (long)Test_To_Run;//test 1a
	mmio.Field3 = (long)PageTable;
	MEM_WRITE(Z502Context, &mmio);   // Initialize Context

	//pass PCB information into PCB created
	newPCB->ContextID = mmio.Field1;
	newPCB->Priority = (int)Priority;
	newPCB->ProcessID = pcbTable->Element_Number ;
	char* newProcessName = (char*)calloc(sizeof(char),16);
	strcpy(newProcessName, (char*)ProcessName);
	newPCB->ProcessName = newProcessName;
	newPCB->ProcessState = PCB_STATE_LIVE;
	newPCB->ProcessLocation = PCB_LOCATION_FLOATING;
	newPCB->TestToRun = Test_To_Run;
	*ProcessID = newPCB->ProcessID;

	//return the PCB created
	return newPCB;
}
Example #24
0
/**************************************************************************
 Test2a exercises a simple memory write and read

 Use:  Z502_REG1                data_written
 Z502_REG2                data_read
 Z502_REG3                address
 Z502_REG4                process_id
 Z502_REG9                error

 In global.h, there's a variable  DO_MEMORY_DEBUG.   Switching it to
 TRUE will allow you to see what the memory system thinks is happening.
 WARNING - it's verbose -- and I don't want to see such output - it's
 strictly for your debugging pleasure.
 **************************************************************************/
void test2a(void)
{

    GET_PROCESS_ID("", &Z502_REG4, &Z502_REG9);

    printf("Release %s:Test 2a: Pid %ld\n", CURRENT_REL, Z502_REG4);
    Z502_REG3 = 412;
    Z502_REG1 = Z502_REG3 + Z502_REG4;
    MEM_WRITE(Z502_REG3, &Z502_REG1);

    MEM_READ(Z502_REG3, &Z502_REG2);

    printf("PID= %ld  address= %ld   written= %ld   read= %ld\n", Z502_REG4,
           Z502_REG3, Z502_REG1, Z502_REG2);
    if (Z502_REG2 != Z502_REG1)
        printf("AN ERROR HAS OCCURRED.\n");
    TERMINATE_PROCESS(-1, &Z502_REG9);

} // End of test2a   
Example #25
0
void disk_write(long disk_id,long sector_id,char* write_buffer) {
    /* Do the hardware call to put data on disk */
    INT32 diskstatus;
    MEM_WRITE(Z502DiskSetID, &disk_id);
    MEM_READ(Z502DiskStatus, &diskstatus);
    if (diskstatus == DEVICE_FREE) {       // Disk hasn't been used - should be free


    }
    if(diskstatus == DEVICE_IN_USE) {
        Running->disk_id = disk_id;
        add_to_diskQ(Running);
        Running = NULL;
        dispatcher();
        /*Z502SwitchContext( SWITCH_CONTEXT_SAVE_MODE, &(Running->context) );*/
        MEM_WRITE(Z502DiskSetID, &disk_id);
        MEM_READ(Z502DiskStatus, &diskstatus);
    }
    MEM_WRITE(Z502DiskSetSector, &sector_id);
    MEM_WRITE(Z502DiskSetBuffer, (INT32 * )write_buffer);
    diskstatus = 1;                        // Specify a write
    MEM_WRITE(Z502DiskSetAction, &diskstatus);
    diskstatus = 0;                        // Must be set to 0
    MEM_WRITE(Z502DiskStart, &diskstatus);
    // Disk should now be started - let's see
    /* MEM_WRITE(Z502DiskSetID, &disk_id);
     MEM_READ(Z502DiskStatus, &diskstatus);
     while (diskstatus != DEVICE_FREE) {
       Z502Idle();
       MEM_READ(Z502DiskStatus, &diskstatus);
     }*/
    Running->disk_id = disk_id;
    return_readyQ(Running);
    Running = NULL;
    dispatcher();
    /*Z502SwitchContext( SWITCH_CONTEXT_SAVE_MODE, &(Running->context) );*/

}
Example #26
0
void sample_code(void) {
	INT32 i, j, k; /* Index & counters       */
	long Value;

	INT32 disk_id, sector; /* Used for disk requests */
	char disk_buffer_write[PGSIZE ];
	char disk_buffer_read[PGSIZE ];
	char physical_memory_write[PGSIZE ];
	char physical_memory_read[PGSIZE ];

	void *context_pointer; /* Used for context commands*/
	void *starting_address;
	BOOL kernel_or_user;
	short random_buckets[NUM_RAND_BUCKETS];
	INT32 LockResult;

	INT32 Status;
	INT32 Temp, Temp1;

	/*********************************************************************
	 Show the interface to the delay timer.
	 Eventually the timer will interrupt ( in base.c there's a handler for
	 this ), but here in sample_code.c we're merely showing the interface
	 to start the call.
	 *********************************************************************/
	MEM_READ(Z502TimerStatus, &Status);
	if (Status == DEVICE_FREE)
		printf("Got expected result for Status of Timer\n");
	else
		printf("Got erroneous result for Status of Timer\n");

	Temp = 777; /* You pick the time units */
	MEM_WRITE(Z502TimerStart, &Temp);
	MEM_READ(Z502TimerStatus, &Status);
	if (Status == DEVICE_IN_USE)
		printf("Got expected result for Status of Timer\n");
	else
		printf("Got erroneous result for Status of Timer\n");
	printf("The next output from the Interrupt Handler should report that \n");
	printf("   interrupt of device 4 has occurred with no error.\n");
	Z502Idle();                //  Let the interrupt for this timer occur

	//  Now we're going to try an illegal time and ensure that the fault
	// handler reports an illegal status.
	Temp = -77; /* You pick the time units */
	printf("The next output from the Interrupt Handler should report that \n");
	printf(
			"   interrupt of device 4 has occurred with an ERR_BAD_PARAM = 1.\n");
	MEM_WRITE(Z502TimerStart, &Temp);
	MEM_READ(Z502TimerStatus, &Status);
	if (Status == DEVICE_FREE)          // Bogus value shouldn't start timer
		printf("Got expected result for Status of Timer\n");
	else
		printf("Got erroneous result for Status of Timer\n");
	fflush(stdout);
	//   ZCALL( Z502_IDLE() );           //  Let the interrupt for this timer occur

	/*  The interrupt handler will have exercised the code doing
	 Z502InterruptDevice,  Z502InterruptStatus, and Z502InterruptClear.
	 But they will have been tested only for "correct" usage.
	 Let's try a few erroneous/illegal operations.          */

	// Set an illegal device as target of our query
	Temp = LARGEST_STAT_VECTOR_INDEX + 1;
	MEM_WRITE(Z502InterruptDevice, &Temp);
	// Now read the status of this device
	MEM_READ(Z502InterruptStatus, &Status);
	if (Status == ERR_BAD_DEVICE_ID)
		printf("Got expected result for Status of Illegal Device\n");
	else
		printf("Got erroneous result for Status of Illegal Device\n");

	/*********************************************************************
	 Show the interface to the Z502_CLOCK.
	 This is easy - all we're going to do is read it twice and make sure
	 the time is incrementing.
	 *********************************************************************/

	MEM_READ(Z502ClockStatus, &Temp);
	MEM_READ(Z502ClockStatus, &Temp1);
	if (Temp1 > Temp)
		printf("The clock time incremented correctly - %d1, %d2\n", Temp,
				Temp1);
	else
		printf("The clock time did NOT increment correctly - %d1, %d2\n", Temp,
				Temp1);

	/*********************************************************************
	 Show the interface to the disk read and write.
	 Eventually the disk will interrupt ( in base.c there's a handler for
	 this ), but here in sample_code.c we're merely showing the interface
	 to start the call.
	 *********************************************************************/

	disk_id = 1; /* Pick arbitrary disk location             */
	sector = 3;
	/* Put data into the buffer being written   */
	strncpy(disk_buffer_write, "123456789abcdef", 15);
	/* Do the hardware call to put data on disk */
	MEM_WRITE(Z502DiskSetID, &disk_id);
	MEM_READ(Z502DiskStatus, &Temp);
	if (Temp == DEVICE_FREE)        // Disk hasn't been used - should be free
		printf("Got expected result for Disk Status\n");
	else
		printf("Got erroneous result for Disk Status - Device not free.\n");
	MEM_WRITE(Z502DiskSetSector, &sector);
	MEM_WRITE(Z502DiskSetBuffer, (INT32 * )disk_buffer_write);
	Temp = 1;                        // Specify a write
	MEM_WRITE(Z502DiskSetAction, &Temp);
	Temp = 0;                        // Must be set to 0
	MEM_WRITE(Z502DiskStart, &Temp);
	// Disk should now be started - let's see
	MEM_WRITE(Z502DiskSetID, &disk_id);
	MEM_READ(Z502DiskStatus, &Temp);
	if (Temp == DEVICE_IN_USE)        // Disk should report being used
		printf("Got expected result for Disk Status\n");
	else
		printf("Got erroneous result for Disk Status\n");

	/* Wait until the disk "finishes" the write. the write is an
	 "unpended-io", meaning the call returns before the work is
	 completed.  By doing the IDLE here, we wait for the disk
	 action to complete.    */
	MEM_WRITE(Z502DiskSetID, &disk_id);
	MEM_READ(Z502DiskStatus, &Temp);
	while (Temp != DEVICE_FREE) {
		Z502Idle();
		MEM_READ(Z502DiskStatus, &Temp);
	}
	/* Now we read the data back from the disk.  If we're lucky,
	 we'll read the same thing we wrote!                     */

	MEM_WRITE(Z502DiskSetSector, &sector);
	MEM_WRITE(Z502DiskSetBuffer, (INT32 * )disk_buffer_read);
	Temp = 0;                        // Specify a read
	MEM_WRITE(Z502DiskSetAction, &Temp);
	Temp = 0;                        // Must be set to 0
	MEM_WRITE(Z502DiskStart, &Temp);

	/* wait for the disk action to complete.  */
	MEM_WRITE(Z502DiskSetID, &disk_id);
	MEM_READ(Z502DiskStatus, &Temp);
	while (Temp != DEVICE_FREE) {
		Z502Idle();
		MEM_READ(Z502DiskStatus, &Temp);
	}

	printf("\n\nThe disk data written is: %s\n", disk_buffer_write);
	printf("The disk data read    is: %s\n", disk_buffer_read);

	/*********************************************************************
	 Let's try some intentional errors to see what happens
	 *********************************************************************/
	Temp = 0;                        // Must be set to 0
	MEM_WRITE(Z502DiskStart, &Temp);
	// Try reading the status without setting an ID
	MEM_READ(Z502DiskStatus, &Temp);
	if (Temp == ERR_BAD_DEVICE_ID)
		printf("Got expected result for Disk Status when using no ID\n");
	else
		printf("Got erroneous result for Disk Status when using no ID\n");

	// Try entering a bad ID and then reading the status
	disk_id = 999;
	MEM_WRITE(Z502DiskSetID, &disk_id);
	MEM_READ(Z502DiskStatus, &Temp);
	if (Temp == ERR_BAD_DEVICE_ID)
		printf("Got expected result for Disk Status when using bad ID\n");
	else
		printf("Got erroneous result for Disk Status when using bad ID\n");

	//  Try doing everything right EXCEPT entering the buffer address,
	disk_id = 1; /* Pick arbitrary disk location             */
	sector = 3;

	MEM_WRITE(Z502DiskSetID, &disk_id);
	MEM_WRITE(Z502DiskSetSector, &sector);
// Don't do this ->    MEM_WRITE( Z502DiskSetBuffer, (INT32 *)disk_buffer_write );
	Temp = 1;                        // Specify a write
	MEM_WRITE(Z502DiskSetAction, &Temp);
	Temp = 0;                        // Must be set to 0
	MEM_WRITE(Z502DiskStart, &Temp);
	// Disk should now not be started - it was missing vital info
	MEM_WRITE(Z502DiskSetID, &disk_id);
	MEM_READ(Z502DiskStatus, &Temp);
	if (Temp == DEVICE_FREE)        // Disk should report being free
		printf("Got expected result for Disk Status when missing data\n");
	else
		printf("Got erroneous result for Disk Status when missing data\n");
	/*********************************************************************
	 Some of the tests put thousands of pages of data on the disk.  Let's
	 see if we can do that here.   The pages ARE being written to the disk,
	 but the interrupt handler doesn't show all of them happening because
	 it's not catching multiple interrupts.
	 *********************************************************************/

	disk_id = 1;
	sector = 0;
	printf("The following section will take a few seconds\n");
	for (j = 0; j < VIRTUAL_MEM_PGS + 100 /* arbitrary # */; j++) {
		MEM_WRITE(Z502DiskSetID, &disk_id);
		MEM_WRITE(Z502DiskSetSector, &sector);
		MEM_WRITE(Z502DiskSetBuffer, (INT32 * )disk_buffer_write);
		Temp = 1;                        // Specify a write
		MEM_WRITE(Z502DiskSetAction, &Temp);
		Temp = 0;                        // Start the disk
		MEM_WRITE(Z502DiskStart, &Temp);
		MEM_WRITE(Z502DiskSetID, &disk_id);
		MEM_READ(Z502DiskStatus, &Temp);
		while (Temp == DEVICE_IN_USE)        // Disk should report being used
		{
			//printf( "Got erroneous result for Disk Status when writing lots of blocks\n" );
			Temp = 5; /* You pick the time units */
			MEM_WRITE(Z502TimerStart, &Temp);
			MEM_READ(Z502DiskStatus, &Temp);
		}
		sector++;
		if (sector >= NUM_LOGICAL_SECTORS) {
			sector = 0;
			disk_id++;
		}
	}
	/*********************************************************************
	 Do a physical memory access to check out that it works.
	 *********************************************************************/
	printf("\nStarting test of physical memory write and read.\n");
	for (i = 0; i < PGSIZE ; i++) {
		physical_memory_write[i] = i;
	}
	Z502WritePhysicalMemory(17, (char *) physical_memory_write);
	Z502ReadPhysicalMemory(17, (char *) physical_memory_read);
	for (i = 0; i < PGSIZE ; i++) {
		if (physical_memory_write[i] != physical_memory_read[i])
			printf("Error in Physical Memory Access\n");
	}
	printf("Completed test of physical memory write and read.\n");
	/*********************************************************************
	 Start all of the disks at the same time and see what happens.
	 *********************************************************************/
	/*
	 sector   = 0;
	 for ( disk_id = 1; disk_id <= MAX_NUMBER_OF_DISKS  ; disk_id++ )
	 {
	 MEM_WRITE( Z502DiskSetID, &disk_id );
	 MEM_WRITE( Z502DiskSetSector, &sector );
	 MEM_WRITE( Z502DiskSetBuffer, (INT32 *)disk_buffer_write );
	 Temp = 1;                        // Specify a write
	 MEM_WRITE( Z502DiskSetAction, &Temp );
	 Temp = 0;                        // Start the disk
	 MEM_WRITE( Z502DiskStart, &Temp );
	 sector++;
	 }
	 //  Now wait until all disks have finished
	 for ( disk_id = 1; disk_id <= MAX_NUMBER_OF_DISKS  ; disk_id++ )
	 {
	 MEM_WRITE( Z502DiskSetID, &disk_id );
	 MEM_READ( Z502DiskStatus, &Temp );
	 while ( Temp == DEVICE_IN_USE )        // Disk should report being used
	 {
	 //ZCALL( Z502_IDLE() );
	 DoSleep(50);
	 }
	 }
	 */
	printf("Disk multiple-block test is complete\n\n");

	/*********************************************************************
	 Show the interface to read and write of real memory
	 It turns out, that though these are hardware calls, the Z502
	 assumes the calls are being made in user mode.  Because the
	 process we're running here in "sample" is in kernel mode,
	 the calls don't work correctly.  For working examples of
	 these calls, see test2a.
	 *********************************************************************/

	Z502_PAGE_TBL_LENGTH = 64;
	Z502_PAGE_TBL_ADDR = (UINT16 *) calloc(sizeof(UINT16),
			Z502_PAGE_TBL_LENGTH);
	i = PTBL_VALID_BIT;
	Z502_PAGE_TBL_ADDR[0] = (UINT16) i;
	i = 73;
	MEM_WRITE(0, &i);
	MEM_READ(0, &j);
	/*  WE expect the data read back to be the same as what we wrote  */
	if (i == j)
		printf("Memory write and read completed successfully\n");
	else
		printf("Memory write and read were NOT successful.\n");

	/*********************************************************************
	 This is the interface to the locking mechanism.  These are hardware
	 interlocks.  We need to test that they work here.  This is the
	 interface we'll be using.

	 void    Z502_READ_MODIFY( INT32 VirtualAddress, INT32 NewLockValue,
	 INT32 Suspend, INT32 *LockResult )

	 We've defined these above to help remember them.
	 #define                  DO_LOCK                     1
	 #define                  DO_UNLOCK                   0
	 #define                  SUSPEND_UNTIL_LOCKED        TRUE
	 #define                  DO_NOT_SUSPEND              FALSE

	 *********************************************************************/

	printf("++++  Starting Hardware Interlock Testing   ++++\n");

	//  TRY A SERIES OF CALLS AS DESCRIBED HERE
	printf("These tests map into the matrix describing the Z502_READ_MODIFY\n");
	printf("     described in Appendix A\n\n");

	printf(
			"1.  Start State = Unlocked:  Action (Thread 1) = Lock: End State = Locked\n");
	READ_MODIFY(MEMORY_INTERLOCK_BASE, DO_LOCK, SUSPEND_UNTIL_LOCKED,
			&LockResult);
	printf("%s\n", &(Success[SPART * LockResult]));

	printf(
			"2.  Start State = locked(1): Action (Thread 1) = unLock: End State = UnLocked\n");
	READ_MODIFY(MEMORY_INTERLOCK_BASE, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
			&LockResult);
	printf("%s\n", &(Success[SPART * LockResult]));

	printf(
			"3.  Start State = Unlocked:  Action (Thread 1) = unLock: End State = UnLocked\n");
	printf("    An Error is Expected\n");
	READ_MODIFY(MEMORY_INTERLOCK_BASE, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
			&LockResult);
	printf("%s\n", &(Success[SPART * LockResult]));

	printf(
			"4.  Start State = unlocked:  Action (Thread 1) = tryLock: End State = Locked\n");
	READ_MODIFY(MEMORY_INTERLOCK_BASE, DO_LOCK, DO_NOT_SUSPEND, &LockResult);
	printf("%s\n", &(Success[SPART * LockResult]));

	printf(
			"5.  Start State = Locked(1): Action (Thread 1) = tryLock: End State = Locked\n");
	READ_MODIFY(MEMORY_INTERLOCK_BASE, DO_LOCK, DO_NOT_SUSPEND, &LockResult);
	printf("%s\n", &(Success[SPART * LockResult]));

	printf(
			"6.  Start State = locked(1): Action (Thread 1) = unLock: End State = UnLocked\n");
	READ_MODIFY(MEMORY_INTERLOCK_BASE, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
			&LockResult);
	printf("%s\n", &(Success[SPART * LockResult]));

	printf(
			"7.  Start State = Unlocked:  Action (Thread 1) = Lock: End State = Locked\n");
	READ_MODIFY(MEMORY_INTERLOCK_BASE, DO_LOCK, SUSPEND_UNTIL_LOCKED,
			&LockResult);
	printf("%s\n", &(Success[SPART * LockResult]));

	//  A thread that locks an item it has already locked will succeed
	printf(
			"8.  Start State = locked(1): Action (Thread 1) = Lock: End State = Locked\n");
	READ_MODIFY(MEMORY_INTERLOCK_BASE, DO_LOCK, SUSPEND_UNTIL_LOCKED,
			&LockResult);
	printf("%s\n", &(Success[SPART * LockResult]));

	// Locking a thread that's already locked - but do it with a thread
	// other than the one that did the locking.
	printf(
			"9.  Start State = Locked(1): Action (Thread 2) = tryLock: End State = Locked\n");
	printf("    An Error is Expected\n");
	Status = CreateAThread((int *) DoOnelock, &Temp);
	DoSleep(100); /*  Wait for that thread to finish   */

	// Unlock a thread that's already locked - but unlock it with a thread
	// other than the one that did the locking.
	printf(
			"10. Start State = Locked(1): Action (Thread 2) = unLock: End State = Locked\n");
	printf("    An Error is Expected\n");
	Status = CreateAThread((int *) DoOneUnlock, &Temp);
	DoSleep(100); /*  Wait for that thread to finish   */

	// The second thread will try to get the lock held by the first thread.  This is OK
	// but the second thread will suspend until the first thread releases the lock.
	printf(
			"11. Start State = Locked(1): Action (Thread 2) = Lock: End State = Locked\n");
	Status = CreateAThread((int *) DoOneTrylock, &Temp);
	DoSleep(100); /*  Wait for that thread to finish   */

	//  The first thread does an unlock.  This means the second thread is now able to get
	//  the lock so there is a "relock" when thread two succeeds.
	printf(
			"12. Start State = locked(1): Action (Thread 1) = unLock: End State = Locked(by 2)\n");
	READ_MODIFY(MEMORY_INTERLOCK_BASE, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
			&LockResult);
	printf("%s\n", &(Success[SPART * LockResult]));
	DoSleep(100); /*  Wait for locking action of 2nd thread to finish   */

	printf(
			"13. Start State = Locked(2): Action (Thread 3) = unLock: End State = Locked(2)\n");
	printf("    An Error is Expected\n");
	Status = CreateAThread((int *) DoOneUnlock, &Temp);
	DoSleep(100); /*  Wait for that thread to finish   */

	printf(
			"14. Start State = Locked(2): Action (Thread 1) = tryLock: End State = Locked(2)\n");
	READ_MODIFY(MEMORY_INTERLOCK_BASE, DO_LOCK, DO_NOT_SUSPEND, &LockResult);
	printf("%s\n", &(Success[SPART * LockResult]));

	printf(
			"15. Start State = locked(2): Action (Thread 1) = unLock: End State = Locked(2)\n");
	printf("    An Error is Expected\n");
	READ_MODIFY(MEMORY_INTERLOCK_BASE, DO_UNLOCK, SUSPEND_UNTIL_LOCKED,
			&LockResult);
	printf("%s\n", &(Success[SPART * LockResult]));

	printf("++++  END of hardware interlock code  ++++\n\n");

	/*********************************************************************
	 Show the interface to the CONTEXT calls.   We aren't going to do a
	 SWITCH_CONTEXT here, because that would cause us to start a
	 process in a strange place and we might never return here.

	 But we do all the setup required.
	 *********************************************************************/

	/* The context_pointer is returned by the MAKE_CONTEXT call.        */

	starting_address = (void *) starting_point_for_new_context;
	kernel_or_user = USER_MODE;
	Z502MakeContext(&context_pointer, starting_address, kernel_or_user);
	Z502DestroyContext(&context_pointer);

	/*********************************************************************
	 Show the interface to the scheduler printer.
	 *********************************************************************/

	CALL(SP_setup( SP_TIME_MODE, 99999 ));
	CALL(SP_setup_action( SP_ACTION_MODE, "CREATE" ));
	CALL(SP_setup( SP_TARGET_MODE, 99L ));
	CALL(SP_setup( SP_RUNNING_MODE, 99L ));
	for (j = 0; j < SP_MAX_NUMBER_OF_PIDS ; j++)
		CALL(SP_setup( SP_READY_MODE, j ));
	for (j = 0; j < SP_MAX_NUMBER_OF_PIDS ; j++)
		CALL(SP_setup( SP_WAITING_MODE, j+20 ));
	for (j = 0; j < SP_MAX_NUMBER_OF_PIDS ; j++)
		CALL(SP_setup( SP_SUSPENDED_MODE, j+40 ));
	for (j = 0; j < SP_MAX_NUMBER_OF_PIDS ; j++)
		CALL(SP_setup( SP_SWAPPED_MODE, j+60 ));
	for (j = 0; j < SP_MAX_NUMBER_OF_PIDS ; j++)
		CALL(SP_setup( SP_TERMINATED_MODE, j+80 ));
	for (j = 0; j < SP_MAX_NUMBER_OF_PIDS ; j++)
		CALL(SP_setup( SP_NEW_MODE, j+50 ));
	CALL(SP_print_header());
	CALL(SP_print_line());

	/*********************************************************************
	 Show the interface to the memory_printer.
	 *********************************************************************/

	for (j = 0; j < 64; j = j + 2) {
		MP_setup((INT32) (j), (INT32) (j / 2) % 10, (INT32) j * 16 + 10,
				(INT32) (j / 2) % 8);
	}
	MP_print_line();

	/*********************************************************************
	 Show how the skewed random numbers work on this platform.
	 *********************************************************************/

	for (j = 0; j < NUM_RAND_BUCKETS; j++)
		random_buckets[j] = 0;

	for (j = 0; j < 100000; j++) {
		get_skewed_random_number(&Value, NUM_RAND_BUCKETS);
		random_buckets[Value]++;
	}
	printf("\nTesting that your platform produces correctly skewed random\n");
	printf("numbers.  Each row should have higher count than the previous.\n");
	printf("    Range:   Counts in this range.\n");
	for (j = 0; j < NUM_RAND_BUCKETS; j = j + 8) {
		k = 0;
		for (i = j; i < j + 8; i++)
			k += random_buckets[i];
		printf("%3d - %3d:  %d\n", j, j + 7, k);
	}

	/*********************************************************************
	 Show the interface to the Z502Halt.
	 Note that the program will end NOW, since we don't return
	 from the command.
	 *********************************************************************/

	Z502Halt();

}
Example #27
0
void    fault_handler( void )
{
    INT32       device_id;
    INT32       status;
    INT32       Index = 0;
    Frame       *f;
    int          i;
    int          victim=0;
    int          diskid;
    UINT16       pagenum;
    UINT16       framenum;
    UINT16       sectorID;

    // Get cause of interrupt
    MEM_READ(Z502InterruptDevice, &device_id );
    // Set this device as target of our query
    MEM_WRITE(Z502InterruptDevice, &device_id );
    // Now read the status of this device
    MEM_READ(Z502InterruptStatus, &status );

    /* printf( "Fault_handler: Found vector type %d with value %d\n",
                         device_id, status );*/
    diskid = 1;
    if(device_id!=4) {
        if(status>=1024) {
            printf("page overflow!\n");
            Z502Halt();
        }
        if(Z502_PAGE_TBL_ADDR == NULL) {
            Z502_PAGE_TBL_LENGTH = 1024;
            Z502_PAGE_TBL_ADDR = (UINT16 *) calloc(sizeof(UINT16),
                                                   Z502_PAGE_TBL_LENGTH);
        }

        //here we initialize the page table
        //f = get_free_frame();
        if(FrameAllUsed != 1) {
            for(i=0; i<64; i++) {
                if(frame[i].framestatus == 0) {
                    frame[i].pagenumber = status;
                    frame[i].framestatus =1;
                    frame[i].pid = Running->pid;
                    Z502_PAGE_TBL_ADDR[frame[i].pagenumber] = (UINT16)frame[i].framenumber | 0x8000;
                    break;
                }

            }
            if(i == 64)
                FrameAllUsed = 1;
        }
        else {
            i = victim;
            framenum = frame[i].framenumber;
            pagenum = frame[i].pagenumber;
            sectorID = pagenum;
            Z502_PAGE_TBL_ADDR[frame[i].pagenumber] = Z502_PAGE_TBL_ADDR[frame[i].pagenumber] & 0x7FFF;

            if(shadowTBL[pagenum].status == 0) {
                shadowTBL[pagenum].framenumber = framenum;
                shadowTBL[pagenum].diskID = diskid;
                shadowTBL[pagenum].sectorID = sectorID;
                shadowTBL[pagenum].status = 1;
                disk_write(shadowTBL[pagenum].diskID, shadowTBL[pagenum].sectorID,(char *)&MEMORY[shadowTBL[pagenum].framenumber * PGSIZE]);
            }

            if(shadowTBL[status].status == 1) {
                shadowTBL[status].status = 0;
                disk_read(shadowTBL[status].diskID, shadowTBL[status].sectorID,(char *)&MEMORY[shadowTBL[status].framenumber * PGSIZE]);
            }

            Z502_PAGE_TBL_ADDR[status] = (UINT16)framenum | 0x8000;
            frame[i].pagenumber = status;
            frame[i].pid = Running->pid;
            frame[i].framestatus = 1;
            victim = (victim + 1) % 64;
        }

    }

    if(device_id==4&&status==0) {
        Z502Halt();
    }
    // Clear out this device - we're done with it
    MEM_WRITE(Z502InterruptClear, &Index );
}                                       /* End of fault_handler */
Example #28
0
void test2f(void)
{
    MEMORY_TOUCHED_RECORD *mtr;
    short Iterations, Index, Loops;

    mtr = (MEMORY_TOUCHED_RECORD *) calloc(1, sizeof (MEMORY_TOUCHED_RECORD));

    GET_PROCESS_ID("", &Z502_REG4, &Z502_REG9);
    printf("\n\nRelease %s:Test 2f: Pid %ld\n", CURRENT_REL, Z502_REG4);

    for (Iterations = 0; Iterations < NUMBER_OF_ITERATIONS; Iterations++)
    {
        for (Index = 0; Index < LOOP_COUNT; Index++) // Bugfix Rel 4.03  12/1/2013
            mtr->page_touched[Index] = 0;
        for (Loops = 0; Loops < LOOP_COUNT; Loops++)
        {
            // Get a random page number
            get_skewed_random_number(&Z502_REG7, LOGICAL_PAGES_TO_TOUCH);
            Z502_REG3 = PGSIZE * Z502_REG7; // Convert page to addr.
            Z502_REG1 = Z502_REG3 + Z502_REG4; // Generate data for page
            MEM_WRITE(Z502_REG3, &Z502_REG1);
            // Write it again, just as a test
            MEM_WRITE(Z502_REG3, &Z502_REG1);

            // Read it back and make sure it's the same
            MEM_READ(Z502_REG3, &Z502_REG2);
            if (Loops % DISPLAY_GRANULARITY2 == 0)
                printf("PID= %ld  address= %ld   written= %ld   read= %ld\n",
                       Z502_REG4, Z502_REG3, Z502_REG1, Z502_REG2);
            if (Z502_REG2 != Z502_REG1)
                printf("AN ERROR HAS OCCURRED: READ NOT EQUAL WRITE.\n");

            // Record in our data-base that we've accessed this page
            mtr->page_touched[(short) Loops] = Z502_REG7;

        } // End of for Loops

        for (Loops = 0; Loops < LOOP_COUNT; Loops++)
        {

            // We can only read back from pages we've previously
            // written to, so find out which pages those are.
            Z502_REG6 = mtr->page_touched[(short) Loops];
            Z502_REG3 = PGSIZE * Z502_REG6; // Convert page to addr.
            Z502_REG1 = Z502_REG3 + Z502_REG4; // Expected read
            MEM_READ(Z502_REG3, &Z502_REG2);

            if (Loops % DISPLAY_GRANULARITY2 == 0)
                printf("PID= %ld  address= %ld   written= %ld   read= %ld\n",
                       Z502_REG4, Z502_REG3, Z502_REG1, Z502_REG2);
            if (Z502_REG2 != Z502_REG1)
                printf("ERROR HAS OCCURRED: READ NOT SAME AS WRITE.\n");
        } // End of for Loops

        // We've completed reading back everything
        printf("TEST 2f, PID %ld, HAS COMPLETED %d ITERATIONS\n", Z502_REG4,
               Iterations);
    } // End of for Iterations

    TERMINATE_PROCESS(-1, &Z502_REG9);

} // End of test2f
static inline void mfc_write_shared_mem_item(unsigned int host_wr_addr, unsigned int addr, unsigned int value)
{
	MEM_WRITE(host_wr_addr + addr, value);
}
Example #30
0
File: Utils.c Project: zhshr/CS502
void CPU_Idle() {
	MEMORY_MAPPED_IO mmio;
	mmio.Mode = Z502Action;
	MEM_WRITE(Z502Idle, &mmio);
}