int TermDriver(void *arg){ int unit = (int) arg; termReaderMB[unit] = P2_MboxCreate(1,INT_SIZE); termLookAhead[unit] = P2_MboxCreate(10,MAX_LINE); termCharToWrite[unit] = P2_MboxCreate(1,INT_SIZE); termWriteSem[unit] = P1_SemCreate(1); termRunningSem[unit] = P1_SemCreate(0); P1_Fork("Term Reader", TermReader, (void *) unit,USLOSS_MIN_STACK, 2); P1_P(termRunningSem[unit]); /*Turn on Terminal interrupts*/ int ctrl = 0; int ctrl2 = 0; ctrl = USLOSS_TERM_CTRL_RECV_INT(ctrl); USLOSS_DeviceOutput(USLOSS_TERM_DEV,unit,(void *)ctrl); P1_V(running); int status = 0; int c = 0; int result; while(1){ result = P1_WaitDevice(USLOSS_TERM_DEV,unit,&status); if(result != 0 || done != 0){ break; } if(USLOSS_TERM_STAT_RECV(status) == USLOSS_DEV_BUSY){ P2_MboxSend(termReaderMB[unit],&status,&INT_SIZE); } if(USLOSS_TERM_STAT_XMIT(status) == USLOSS_DEV_READY){ if(P2_MboxCondReceive(termCharToWrite[unit],&c,&INT_SIZE) != -2){ ctrl2 = 0; ctrl2 = USLOSS_TERM_CTRL_XMIT_INT(ctrl2); ctrl2 = USLOSS_TERM_CTRL_RECV_INT(ctrl2); ctrl2 = USLOSS_TERM_CTRL_CHAR(ctrl2, c); ctrl2 = USLOSS_TERM_CTRL_XMIT_CHAR(ctrl2); USLOSS_DeviceOutput(USLOSS_TERM_DEV, unit, (void *)ctrl2); }else{ ctrl2 = 0; ctrl2 = USLOSS_TERM_CTRL_RECV_INT(ctrl2); USLOSS_DeviceOutput(USLOSS_TERM_DEV, unit, (void *)ctrl2); } } } status = 0; P2_MboxCondSend(termReaderMB[unit],&ctrl,&status); P1_Join(&status); return unit; }
//write a 512 byte sector to the current track int P2_DiskWrite(int unit, int track, int first, int sectors, void *buffer) { if(permissionCheck() || track < 0 || track >= DISK_TRACKS[unit] || first < 0 || first > 15 || unit < 0 || unit > 1 || sectors <= 0){ return -1; } P1_P(diskSem[unit]); int status = 0; //first make a device request struct for a seek USLOSS_DeviceRequest seekRequest; seekRequest.opr = USLOSS_DISK_SEEK; seekRequest.reg1 = (void *)track; //track number where the r/w head should be moved //make device request struct for write USLOSS_DeviceRequest writeRequest; writeRequest.opr = USLOSS_DISK_WRITE; USLOSS_DeviceOutput(USLOSS_DISK_DEV,unit,&seekRequest); P1_WaitDevice(USLOSS_DISK_DEV,unit,&status); int i = 0; while (sectors != 0 && status == 0) { writeRequest.reg1 = (void *)first; writeRequest.reg2 = buffer + (i * USLOSS_DISK_SECTOR_SIZE); USLOSS_DeviceOutput(USLOSS_DISK_DEV,unit,&writeRequest); P1_WaitDevice(USLOSS_DISK_DEV,unit,&status); if (status == USLOSS_DEV_ERROR) { USLOSS_Console("Error with disk write request, unit %d, track %d, sector %d\n",unit, track, first); } first++; sectors--; if (first == 16 && sectors > 0) { //need to move on to next track. track++; seekRequest.reg1 = (void *) track; USLOSS_DeviceOutput(USLOSS_DISK_DEV,unit,&seekRequest); P1_WaitDevice(USLOSS_DISK_DEV,unit,&status); first = 0; //set first to 0 sector of new track } writeRequest.reg1 = (void *)first; i++; } P1_V(diskSem[unit]); return status; }
/*P2_DiskSize() returns info about the size of the disk indicated by unit*/ int P2_DiskSize(int unit, int *sector, int *track, int *disk) { if(permissionCheck() || unit < 0 || unit > 1){ return -1; } P1_P(diskSem[unit]); int status; *sector = USLOSS_DISK_SECTOR_SIZE; *track = USLOSS_DISK_TRACK_SIZE; // Make device request for finding number of tracks in disk USLOSS_DeviceRequest request; request.opr = USLOSS_DISK_TRACKS; //reg1 contains pointer to integer where number of disk tracks will be stored request.reg1 = disk; USLOSS_DeviceOutput(USLOSS_DISK_DEV,unit,&request); P1_WaitDevice(USLOSS_DISK_DEV,unit,&status); P1_V(diskSem[unit]); return 0; }
void startup() { int status; int i, j, k; FILE *f; char name[50]; int n; // Compute the inputs and write them to the term*.in file. Each terminal reads unique content. k = 0; for(i = 0; i < USLOSS_TERM_UNITS; i++) { memset(buffers[i], '\0', NUMCHARS); counts[i] = 0; snprintf(name, sizeof(name), "term%d.in", i); f = fopen(name, "w"); assert(f != NULL); for (j = 0; j < NUMCHARS; j++) { inputs[i][j] = 'a' + k++; } n = fwrite(inputs[i], 1, NUMCHARS, f); assert(n == NUMCHARS); fclose(f); } for (i = 0; i < USLOSS_NUM_INTS; i++) { USLOSS_IntVec[i] = dummy_handler; } // Turn on receive interrupts. for(i = 0; i < USLOSS_TERM_UNITS; i++) { status = USLOSS_DeviceOutput(USLOSS_TERM_DEV, i, (void *) USLOSS_TERM_CTRL_RECV_INT(0)); } USLOSS_IntVec[USLOSS_TERM_INT] = term_handler; // Turn on interrupts. USLOSS_PsrSet(USLOSS_PsrGet() | USLOSS_PSR_CURRENT_INT); // Read from the terminals. while(done < USLOSS_TERM_UNITS ) { USLOSS_WaitInt(); } USLOSS_Halt(0); }
void startup() { int status; int i; for (i = 0; i < USLOSS_NUM_INTS; i++) { USLOSS_IntVec[i] = dummy_handler; } // Turn on receive interrupts for terminal 0. status = USLOSS_DeviceOutput(USLOSS_TERM_DEV, 0, (void *) USLOSS_TERM_CTRL_RECV_INT(0)); USLOSS_IntVec[USLOSS_TERM_INT] = term_handler; // Turn on interrupts. USLOSS_PsrSet(USLOSS_PsrGet() | USLOSS_PSR_CURRENT_INT); // Wait in an infinite loops for interrupts. while(1) { USLOSS_WaitInt(); } }
int start2(char *arg) { int kid_status, kidpid; int control = 0; USLOSS_Console("start2(): started\n"); control = USLOSS_TERM_CTRL_RECV_INT(control); USLOSS_Console("start2(): calling USLOSS_DeviceOutput to enable receive "); USLOSS_Console("interrupts, control = %d\n", control); USLOSS_DeviceOutput(USLOSS_TERM_DEV, 1, &control); kidpid = fork1("XXp1", XXp1, NULL, 2 * USLOSS_MIN_STACK, 3); kidpid = join(&kid_status); USLOSS_Console("start2(): joined with kid %d, status = %d\n", kidpid, kid_status); quit(0); return 0; /* so gcc will not complain about its absence... */ } /* start2 */
int P2_TermWrite(int unit, int size, char *text){ if(unit >= USLOSS_TERM_UNITS || unit < 0 || size < 0){ return -1; } int ctrl = 0; if(size > P2_MAX_LINE){ size = P2_MAX_LINE; } P1_P(termWriteSem[unit]); int i = 0; int cSize = sizeof(char); int c; while(i < size){ ctrl = USLOSS_TERM_CTRL_XMIT_INT(0); ctrl = USLOSS_TERM_CTRL_RECV_INT(ctrl); USLOSS_DeviceOutput(USLOSS_TERM_DEV, unit, (void *)ctrl); c = *(text + i); P2_MboxSend(termCharToWrite[unit],&c,&cSize); i++; } P1_V(termWriteSem[unit]); P2_Sleep(1); return size; }
int P2_Startup(void *arg) { USLOSS_IntVec[USLOSS_SYSCALL_INT] = sysHandler; /*Init all mailboxes*/ int i; for(i = 0; i < P2_MAX_MBOX;i++){ mailboxes[i].id = i; mailboxes[i].inUse = 0; mailboxes[i].queue = NULL; mailboxes[i].activeSlots = 0; } for(i = 0; i < P1_MAXPROC;i++){ clockList[i].inUse = 0; } for(i = 0; i < P1_MAXSEM;i++){ userSemList[i].id = i; userSemList[i].inUse = 0; } mBoxSemaphore = P1_SemCreate(1); clockListSemaphore = P1_SemCreate(1); semGuard = P1_SemCreate(1); running = P1_SemCreate(0); int status; int pid; int clockPID; /* * Create clock device driver */ clockPID = P1_Fork("Clock driver", ClockDriver, (void *) running, USLOSS_MIN_STACK, 2); if (clockPID == -1) { USLOSS_Console("Can't create clock driver\n"); } /* * Wait for the clock driver to start. */ P1_P(running); for(i = 0; i < USLOSS_TERM_UNITS;i++){ termPids[i] = P1_Fork("Term driver", TermDriver, (void *) i,USLOSS_MIN_STACK, 2); if (termPids[i] == -1) { USLOSS_Console("Can't create term driver. Unit = %d\n",i); } P1_P(running); } int sector,track,disk; for (i = 0; i < USLOSS_DISK_UNITS;i++) { diskSem[i] = P1_SemCreate(1); P2_DiskSize(i,§or,&track,&disk); DISK_TRACKS[i] = disk; } pid = P2_Spawn("P3_Startup", P3_Startup, NULL, 4 * USLOSS_MIN_STACK, 3); pid = P2_Wait(&status); /* * Kill the device drivers */ P1_Kill(clockPID); /*Let everyone know we are done.*/ done = 1; /*Interrupt all terminals*/ int ctrl = 0; ctrl = USLOSS_TERM_CTRL_XMIT_INT(ctrl); ctrl = USLOSS_TERM_CTRL_RECV_INT(ctrl); for(i = 0 ; i < USLOSS_TERM_UNITS;i++){ P1_Kill(termPids[i]); USLOSS_DeviceOutput(USLOSS_TERM_DEV, i, (void *)ctrl); P2_Wait(&status); } /*Interrupt any disk requests*/ USLOSS_DeviceRequest seekRequest; seekRequest.opr = USLOSS_DISK_SEEK; seekRequest.reg1 = (void *)0; for(i = 0 ; i < USLOSS_DISK_UNITS;i++){ USLOSS_DeviceOutput(USLOSS_DISK_DEV,i,(void *)&seekRequest); P2_Wait(&status); } /*Finally wait for the clock driver to be done*/ P2_Wait(&status); return 0; }