Add Syscall: Exit, PutChar, GetCar, PutString, GetString
This commit is contained in:
parent
6f405265a5
commit
80fc250109
15 changed files with 359 additions and 17 deletions
|
@ -31,7 +31,7 @@ THREAD_O := main.o list.o scheduler.o synch.o synchlist.o \
|
|||
stats.o sysdep.o timer.o
|
||||
|
||||
USERPROG_O := addrspace.o bitmap.o exception.o progtest.o console.o \
|
||||
machine.o mipssim.o translate.o
|
||||
consoledriver.o machine.o mipssim.o translate.o
|
||||
|
||||
VM_O :=
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ HOST += -DLINUX
|
|||
CFLAGS += -fsanitize=undefined
|
||||
LDFLAGS += -fsanitize=undefined
|
||||
|
||||
# décommenté TD1 - partie V
|
||||
#CFLAGS += -fsanitize=address
|
||||
#LDFLAGS += -fsanitize=address -lpthread
|
||||
endif
|
||||
|
|
13
code/test/getstring.c
Normal file
13
code/test/getstring.c
Normal file
|
@ -0,0 +1,13 @@
|
|||
#include "syscall.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
//char s;
|
||||
//s = GetChar();
|
||||
//PutChar(s);
|
||||
char t[100];
|
||||
GetString(t, 100);
|
||||
PutString(t);
|
||||
PutChar('\n');
|
||||
PutString("Ceci est un test de grande ampleur");
|
||||
}
|
17
code/test/putchar.c
Normal file
17
code/test/putchar.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include "syscall.h"
|
||||
void print(char c, int n)
|
||||
{
|
||||
int i;
|
||||
//#if 0
|
||||
for (i = 0; i < n; i++) {
|
||||
PutChar(c + i);
|
||||
}
|
||||
PutChar('\n');
|
||||
//#endif
|
||||
}
|
||||
int
|
||||
main()
|
||||
{
|
||||
print('a',4);
|
||||
Halt();
|
||||
}
|
15
code/test/putstring.c
Normal file
15
code/test/putstring.c
Normal file
|
@ -0,0 +1,15 @@
|
|||
#include "syscall.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
// PutString("Te\n");
|
||||
// PutString("Tes\n");
|
||||
// PutString("Tes t\n");
|
||||
// // les deux derniers ne fonctionnent pas car ila dépassent la taille du
|
||||
// // buffer: MAX_STRING_SIZE
|
||||
// //
|
||||
// // Maitenant que j'ai fais une boucle dans PutString, tout fonctionne bien
|
||||
PutString("BonjourTout\n");
|
||||
PutString("Bonjour tout le monde\n");
|
||||
Exit(4);
|
||||
}
|
|
@ -146,6 +146,43 @@ Yield:
|
|||
j $31
|
||||
.end Yield
|
||||
|
||||
#ifdef CHANGED
|
||||
.globl PutChar
|
||||
.ent PutChar
|
||||
PutChar:
|
||||
addiu $2,$0,SC_PutChar
|
||||
syscall
|
||||
j $31
|
||||
.end PutChar
|
||||
|
||||
|
||||
.globl PutString
|
||||
.ent PutString
|
||||
PutString:
|
||||
addiu $2,$0,SC_PutString
|
||||
syscall
|
||||
j $31
|
||||
.end PutString
|
||||
|
||||
.globl GetChar
|
||||
.ent GetChar
|
||||
|
||||
GetChar:
|
||||
addiu $2,$0,SC_GetChar
|
||||
syscall
|
||||
j $31
|
||||
.end PutChar
|
||||
|
||||
|
||||
.globl GetString
|
||||
.ent GetString
|
||||
GetString:
|
||||
addiu $2,$0,SC_GetString
|
||||
syscall
|
||||
j $31
|
||||
.end GetString
|
||||
#endif
|
||||
|
||||
/* dummy function to keep gcc happy */
|
||||
.globl __main
|
||||
.ent __main
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
#include "utility.h"
|
||||
#include "system.h"
|
||||
|
||||
#ifdef USER_PROGRAM
|
||||
#include "progtest.h"
|
||||
#endif
|
||||
|
@ -118,6 +117,7 @@ main (int argc, char **argv)
|
|||
if (!strcmp (*argv, "-x"))
|
||||
{ // run a user program
|
||||
ASSERT (argc > 1);
|
||||
consoledriver = new ConsoleDriver(NULL,NULL);
|
||||
StartProcess (*(argv + 1));
|
||||
argCount = 2;
|
||||
}
|
||||
|
@ -132,6 +132,19 @@ main (int argc, char **argv)
|
|||
argCount = 3;
|
||||
}
|
||||
}
|
||||
#ifdef CHANGED
|
||||
else if (!strcmp (*argv, "-sc"))
|
||||
{ // test the consoledriver
|
||||
if (argc == 1)
|
||||
ConsoleDriverTest (NULL, NULL);
|
||||
else
|
||||
{
|
||||
ASSERT (argc > 2);
|
||||
ConsoleDriverTest (*(argv + 1), *(argv + 2));
|
||||
argCount = 3;
|
||||
}
|
||||
}
|
||||
#endif // CHANGE
|
||||
#endif // USER_PROGRAM
|
||||
#ifdef FILESYS
|
||||
if (!strcmp (*argv, "-cp"))
|
||||
|
|
|
@ -33,7 +33,12 @@ SynchDisk *synchDisk;
|
|||
|
||||
#ifdef USER_PROGRAM // requires either FILESYS or FILESYS_STUB
|
||||
Machine *machine; // user program memory and registers
|
||||
#endif
|
||||
|
||||
#ifdef CHANGED // Define our consoledriver Object
|
||||
ConsoleDriver *consoledriver;
|
||||
#endif // CHANGED
|
||||
|
||||
#endif // USER_PROGRAM
|
||||
|
||||
#ifdef NETWORK
|
||||
PostOffice *postOffice;
|
||||
|
@ -230,6 +235,12 @@ Cleanup ()
|
|||
delete machine;
|
||||
machine = NULL;
|
||||
}
|
||||
#ifdef CHANGED
|
||||
if (consoledriver) {
|
||||
delete consoledriver;
|
||||
consoledriver = NULL;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef FILESYS_NEEDED
|
||||
|
|
|
@ -32,6 +32,13 @@ extern Timer *timer; // the hardware alarm clock
|
|||
#ifdef USER_PROGRAM
|
||||
#include "machine.h"
|
||||
extern Machine *machine; // user program memory and registers
|
||||
|
||||
#ifdef CHANGED
|
||||
#define MAX_STRING_SIZE 8
|
||||
#include "consoledriver.h"
|
||||
extern ConsoleDriver *consoledriver; // add console driver
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef FILESYS_NEEDED // FILESYS or FILESYS_STUB
|
||||
|
|
66
code/userprog/consoledriver.cc
Normal file
66
code/userprog/consoledriver.cc
Normal file
|
@ -0,0 +1,66 @@
|
|||
#ifdef CHANGED
|
||||
#include "copyright.h"
|
||||
#include "system.h"
|
||||
#include "consoledriver.h"
|
||||
#include "synch.h"
|
||||
|
||||
#define STRINGBUFFER 8
|
||||
|
||||
static Semaphore *readAvail;
|
||||
static Semaphore *writeDone;
|
||||
|
||||
static void ReadAvailHandler(void *arg) { (void) arg; readAvail->V(); }
|
||||
static void WriteDoneHandler(void *arg) { (void) arg; writeDone->V(); }
|
||||
|
||||
ConsoleDriver::ConsoleDriver(const char *in, const char *out)
|
||||
{
|
||||
readAvail = new Semaphore("read avail", 0);
|
||||
writeDone = new Semaphore("write done", 0);
|
||||
console = new Console (in, out, ReadAvailHandler, WriteDoneHandler, NULL);
|
||||
}
|
||||
|
||||
ConsoleDriver::~ConsoleDriver()
|
||||
{
|
||||
delete console;
|
||||
delete writeDone;
|
||||
delete readAvail;
|
||||
}
|
||||
|
||||
void ConsoleDriver::PutChar( int ch)
|
||||
{
|
||||
console->TX(ch);
|
||||
writeDone->P();
|
||||
}
|
||||
|
||||
int ConsoleDriver::GetChar()
|
||||
{
|
||||
readAvail->P();
|
||||
int ch = console->RX();
|
||||
return ch;
|
||||
}
|
||||
|
||||
void ConsoleDriver::PutString(const char s[MAX_STRING_SIZE])
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MAX_STRING_SIZE; i++){
|
||||
if (*(s+i) =='\0'){
|
||||
return;
|
||||
}
|
||||
PutChar(*(s+i));
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleDriver::GetString(char * s, int n)
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < n - 1; i++){
|
||||
char c = GetChar();
|
||||
if ( c == '\0' || c == '\n' || c == EOF) {
|
||||
break;
|
||||
}
|
||||
*(s+i) = c;
|
||||
}
|
||||
*(s+i) = '\0';
|
||||
}
|
||||
|
||||
#endif // CHANGED
|
25
code/userprog/consoledriver.h
Normal file
25
code/userprog/consoledriver.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifdef CHANGED
|
||||
#ifndef CONSOLEDRIVER_H
|
||||
#define CONSOLEDRIVER_H
|
||||
|
||||
#include "copyright.h"
|
||||
#include "utility.h"
|
||||
#include "console.h"
|
||||
|
||||
class ConsoleDriver:dontcopythis {
|
||||
public:
|
||||
// initialize the hardware console device
|
||||
ConsoleDriver(const char *readFile, const char *writeFile);
|
||||
|
||||
~ConsoleDriver(); // clean up
|
||||
|
||||
void PutChar(int ch); // Behaves like putchar(3S)
|
||||
int GetChar(); // Behaves like getchar(3S)
|
||||
|
||||
void PutString(const char *s); // Behaves like fputs(3S)
|
||||
void GetString(char *s, int n); // Behaves like fgets(3S)
|
||||
private:
|
||||
Console *console;
|
||||
};
|
||||
#endif // CONSOLEDRIVER_H
|
||||
#endif // CHANGED
|
|
@ -63,6 +63,37 @@ UpdatePC ()
|
|||
// "which" is the kind of exception. The list of possible exceptions
|
||||
// are in machine.h.
|
||||
//----------------------------------------------------------------------
|
||||
int copyStringFromMachine(int from, char *to, unsigned size)
|
||||
{
|
||||
unsigned i = 0;
|
||||
int res;
|
||||
|
||||
// Need to read size-1 to put final /0 if needed
|
||||
while((i<size-1) && (machine->ReadMem(from+i,1,&res))){
|
||||
*(to+i) = (char)res;
|
||||
if ((char)res == '\0'){
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
*(to+i)='\0';
|
||||
return size;
|
||||
}
|
||||
|
||||
int copyStringToMachine(int to, char* from, unsigned size)
|
||||
{
|
||||
unsigned i;
|
||||
for (i=0; i < size - 1; i++) {
|
||||
if (from[i] == '\0') {
|
||||
break;
|
||||
}
|
||||
machine->WriteMem(to+i,1,(int)from[i]);
|
||||
}
|
||||
|
||||
// Write the last /0
|
||||
machine->WriteMem(to+i,1,'\0');
|
||||
return i;
|
||||
}
|
||||
|
||||
void
|
||||
ExceptionHandler (ExceptionType which)
|
||||
|
@ -82,6 +113,67 @@ ExceptionHandler (ExceptionType which)
|
|||
interrupt->Powerdown ();
|
||||
break;
|
||||
}
|
||||
#ifdef CHANGED
|
||||
case SC_Exit:
|
||||
{
|
||||
int ret = machine->ReadRegister(4);
|
||||
printf("Exit code %d\n", ret);
|
||||
interrupt->Powerdown();
|
||||
break;
|
||||
}
|
||||
case SC_PutChar:
|
||||
{
|
||||
DEBUG ('s', "PutChar.\n");
|
||||
consoledriver->PutChar((char)machine->ReadRegister(4));
|
||||
break;
|
||||
}
|
||||
case SC_PutString:
|
||||
{
|
||||
|
||||
DEBUG ('s', "PutString.\n");
|
||||
int readsize;
|
||||
int addr_start = machine->ReadRegister(4);
|
||||
do {
|
||||
char* read = new char[MAX_STRING_SIZE];
|
||||
readsize = copyStringFromMachine( addr_start, read, MAX_STRING_SIZE);
|
||||
consoledriver->PutString(read);
|
||||
// beware, the last element of our buffer was added by
|
||||
// copyStringFromMachine(), we need to remove one memory case
|
||||
// or the first char of our next read will be
|
||||
// forgotten
|
||||
addr_start += readsize - 1;
|
||||
delete [] read;
|
||||
} while(readsize == MAX_STRING_SIZE);
|
||||
break;
|
||||
}
|
||||
case SC_GetChar:
|
||||
{
|
||||
DEBUG ('s', "GetChar.\n");
|
||||
// Get the char input an write it to the register n.2
|
||||
int c = consoledriver->GetChar();
|
||||
machine->WriteRegister((2), c);
|
||||
break;
|
||||
}
|
||||
|
||||
case SC_GetString:
|
||||
{
|
||||
DEBUG ('s', "GetString.\n");
|
||||
int writesize = 0;
|
||||
int addr = machine->ReadRegister(4);
|
||||
int size = machine->ReadRegister(5);
|
||||
DEBUG ('s', "size:%d\n", size);
|
||||
do {
|
||||
char* write = new char[MAX_STRING_SIZE];
|
||||
consoledriver->GetString(write, MAX_STRING_SIZE);
|
||||
printf("write:%s:\n", write);
|
||||
writesize = copyStringToMachine(addr, write, MAX_STRING_SIZE);
|
||||
addr += writesize;
|
||||
printf("Writed:%d\n", writesize);
|
||||
delete [] write;
|
||||
} while( writesize == MAX_STRING_SIZE - 1 );
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
{
|
||||
printf("Unimplemented system call %d\n", type);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "copyright.h"
|
||||
#include "system.h"
|
||||
#include "consoledriver.h"
|
||||
#include "console.h"
|
||||
#include "addrspace.h"
|
||||
#include "synch.h"
|
||||
|
@ -84,7 +85,7 @@ void
|
|||
ConsoleTest (const char *in, const char *out)
|
||||
{
|
||||
char ch;
|
||||
|
||||
printf("test console\n<");
|
||||
readAvail = new Semaphore ("read avail", 0);
|
||||
writeDone = new Semaphore ("write done", 0);
|
||||
console = new Console (in, out, ReadAvailHandler, WriteDoneHandler, NULL);
|
||||
|
@ -93,14 +94,44 @@ ConsoleTest (const char *in, const char *out)
|
|||
{
|
||||
readAvail->P (); // wait for character to arrive
|
||||
ch = console->RX ();
|
||||
#ifdef CHANGED
|
||||
// My modifications...
|
||||
// Check input before display it...
|
||||
if (ch == 'q' || ch == -1 ) {
|
||||
printf ("au revoir!\n");
|
||||
break; // if q, quit
|
||||
}
|
||||
|
||||
console->TX ('<');
|
||||
writeDone->P ();
|
||||
console->TX (ch); // echo it!
|
||||
writeDone->P (); // wait for write to finish
|
||||
console->TX ('>');
|
||||
writeDone->P ();
|
||||
#else
|
||||
console->TX (ch); // echo it!
|
||||
writeDone->P (); // wait for write to finish
|
||||
if (ch == 'q') {
|
||||
printf ("Nothing more, bye!\n");
|
||||
break; // if q, quit
|
||||
}
|
||||
#endif
|
||||
}
|
||||
delete console;
|
||||
delete readAvail;
|
||||
delete writeDone;
|
||||
}
|
||||
|
||||
#ifdef CHANGED
|
||||
void
|
||||
ConsoleDriverTest (const char *in, const char *out)
|
||||
{
|
||||
printf("test consoledriver\n");
|
||||
char ch;
|
||||
ConsoleDriver *test_consoledriver = new ConsoleDriver(in, out);
|
||||
while ((ch = test_consoledriver->GetChar()) != EOF)
|
||||
test_consoledriver->PutChar(ch);
|
||||
fprintf(stderr, "EOF detected in ConsoleDriver!\n");
|
||||
delete test_consoledriver;
|
||||
}
|
||||
#endif //CHANGED
|
||||
|
|
|
@ -14,5 +14,7 @@
|
|||
extern void StartProcess (char *filename);
|
||||
|
||||
extern void ConsoleTest (const char *in, const char *out);
|
||||
|
||||
#ifdef CHANGED
|
||||
extern void ConsoleDriverTest (const char *in, const char *out);
|
||||
#endif //CHANGED
|
||||
#endif // PROGTEST_H
|
||||
|
|
|
@ -20,18 +20,23 @@
|
|||
/* system call codes -- used by the stubs to tell the kernel which system call
|
||||
* is being asked for
|
||||
*/
|
||||
#define SC_Halt 0
|
||||
#define SC_Exit 1
|
||||
#define SC_Exec 2
|
||||
#define SC_Join 3
|
||||
#define SC_Create 4
|
||||
#define SC_Open 5
|
||||
#define SC_Read 6
|
||||
#define SC_Write 7
|
||||
#define SC_Close 8
|
||||
#define SC_Fork 9
|
||||
#define SC_Yield 10
|
||||
|
||||
#define SC_Halt 0
|
||||
#define SC_Exit 1
|
||||
#define SC_Exec 2
|
||||
#define SC_Join 3
|
||||
#define SC_Create 4
|
||||
#define SC_Open 5
|
||||
#define SC_Read 6
|
||||
#define SC_Write 7
|
||||
#define SC_Close 8
|
||||
#define SC_Fork 9
|
||||
#define SC_Yield 10
|
||||
#ifdef CHANGED
|
||||
#define SC_PutChar 11 // My first SysCall :')
|
||||
#define SC_PutString 12
|
||||
#define SC_GetChar 13
|
||||
#define SC_GetString 14
|
||||
#endif
|
||||
#ifdef IN_USER_MODE
|
||||
|
||||
// LB: This part is read only on compiling the test/*.c files.
|
||||
|
@ -130,6 +135,13 @@ void Fork (void (*func) ());
|
|||
*/
|
||||
void Yield ();
|
||||
|
||||
#ifdef CHANGED
|
||||
void PutChar (char c);
|
||||
void PutString (char * s);
|
||||
void GetChar(char c);
|
||||
void GetString(char * s, int n );
|
||||
#endif // CHANGED
|
||||
|
||||
#endif // IN_USER_MODE
|
||||
|
||||
#endif /* SYSCALL_H */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue