diff --git a/include/umps/umpsconst.h b/include/umps/umpsconst.h index 276ae13..397338d 100644 --- a/include/umps/umpsconst.h +++ b/include/umps/umpsconst.h @@ -31,4 +31,62 @@ #define INTERVAL_TIMER_ON (STATUS_IM(2)) #define INTERVAL_TIMER_OFF (~INTERVAL_TIMER_ON) -#define CAUSE_IP_GET(cause, device) ((cause&CAUSE_IP(device)) != 0) \ No newline at end of file +#define RESET 0 +#define ACK 1 +//-------------------------------------------------------Terminal +/*Terminal Device Status Codes*/ +#define TERM_NOT_INSTALLED 0 +#define TERM_READY 1 +#define TERM_ILLEGAL_OP 2 +#define TERM_BUSY 3 +#define RECV_TRASM_ERR 4 +#define CHAR_RECV_TRASM 5 + +#define IS_TERM_READY(status) ((status&0xFF)==TERM_READY) +#define IS_TERM_IN_ERROR(status) (\ + (status&0xFF)==TERM_NOT_INSTALLED || \ + (status&0xFF)==TERM_ILLEGAL_OP || \ + (status&0xFF)==RECV_TRASM_ERR) +//--------------------------------------------------------------- + +//------------------------------------------------------Other Dev +#define DEV_NOT_INSTALLED 0 +#define DEV_READY 1 +#define ILLEGAL_OP 2 +#define DEV_BUSY 3 +#define ERR_CODE_4 4 +#define ERR_CODE_5 5 +#define ERR_CODE_6 6 +#define ERR_CODE_7 7 +#define ERR_CODE_128 128 + +#define IS_DEV_IN_ERROR(status) (\ + (status&0xFF)==DEV_NOT_INSTALLED || (status&0xFF)==ILLEGAL_OP || \ + (status&0xFF)==ERR_CODE_4 || (status&0xFF)==ERR_CODE_5 \ + (status&0xFF)==ERR_CODE_6 || (status&0xFF)==ERR_CODE_7 \ + (status&0xFF)==ERR_CODE_128) + +//--------------------------------------------------------------- + + + +// +#define CAUSE_IP_GET(cause, line) ((cause&CAUSE_IP(line)) != 0) + +// +#define IS_IRQ_RAISED_FROM_I(line,i) ((i>=0 && i<8 && CDEV_BITMAP_ADDR(line)&(1U<term->transm_status)? (0) : (1))) +// +#define GET_SEM_INDEX(dev_reg,line,device) (N_DEV_PER_IL*(line-DEV_ONLY+GET_SEM_OFFSET(dev_reg,line))+device) +// +#define GET_DEV_STATUS(dev_reg, line) (line!=IL_TERMINAL ?(dev_reg->dtp->status):(GET_SEM_OFFSET(dev_reg,line) ?(dev_reg->term->recv_status):(dev_reg->term->trasm_status)) + + diff --git a/src/handler/uarm/handler.c b/src/handler/uarm/handler.c index 005f062..70b2079 100644 --- a/src/handler/uarm/handler.c +++ b/src/handler/uarm/handler.c @@ -82,38 +82,38 @@ void Handler_TLB(void){ //---------------------------------------------------------------- void Handler_Interrupt(void) { state_t *request = (state_t *) INT_OLDAREA; - word cause = cause = request->CP15_Cause; - word excode = CAUSE_EXCCODE_GET(request->CP15_Cause); + word cause = request->CP15_Cause; + word excode = CAUSE_EXCCODE_GET(request->CP15_Cause); request->pc -= WORD_SIZE; - if (excode != EXC_INTERRUPT) { + if(excode != EXC_INTERRUPT){ PANIC(); } - if ( CAUSE_IP_GET(cause, INT_TIMER) ) { + if(CAUSE_IP_GET(cause, INT_TIMER)){ // Interval Timer - scheduler_StateToReady( request ); + scheduler_StateToReady(request); scheduler_StateToRunning(); return; } - if ( CAUSE_IP_GET(cause, INT_DISK) ) { + if(CAUSE_IP_GET(cause, INT_DISK)){ // Disk Devices return; } - if ( CAUSE_IP_GET(cause, INT_TAPE) ) { + if(CAUSE_IP_GET(cause, INT_TAPE)){ // Tape Devices return; } - if ( CAUSE_IP_GET(cause, INT_UNUSED) ) { + if (CAUSE_IP_GET(cause, INT_UNUSED)){ // Unused return; } - if( CAUSE_IP_GET(cause, INT_PRINTER) ) { + if(CAUSE_IP_GET(cause, INT_PRINTER)){ // Printer Devices return; } - if( CAUSE_IP_GET(cause, INT_TERMINAL) ) { + if(CAUSE_IP_GET(cause, INT_TERMINAL)){ // Terminal Devices return; } diff --git a/src/handler/umps/handler.c b/src/handler/umps/handler.c index 71cc835..a14af27 100644 --- a/src/handler/umps/handler.c +++ b/src/handler/umps/handler.c @@ -23,6 +23,8 @@ #include #include +extern int semdev[SEM_DEV_N]; // la vera struttura dati sarĂ  nell init.c + // Syscall-Breakpoint Handler //--------------------------------------------------------------- void Handler_SysCall(void){ @@ -80,61 +82,104 @@ void Handler_TLB(void) { // Interrupt Handler //---------------------------------------------------------------- void Handler_Interrupt(void) { - state_t *request = (state_t *) INT_OLDAREA; - word exc_cause = CAUSE_GET_EXCCODE(request->cause); - - if (exc_cause != EXC_INT){/*req error*/ - PANIC(); + state_t *request = (state_t *) INT_OLDAREA; + word exc_cause = CAUSE_GET_EXCCODE(request->cause); + + if(exc_cause != EXC_INT){ + PANIC(); /*REQ ERROR*/ } - - //---------------------------------------------------Inter TODO - if (CAUSE_IP_GET(request->cause,IL_IPI)){ /*Future use*/ - PANIC(); + + //----------------------------------------------Inter-processor + if(CAUSE_IP_GET(request->cause,IL_IPI)){ + PANIC(); /*NOT SUPPORTED*/ + } + //--------------------------Processor Local Timer/Interval Timer + if(CAUSE_IP_GET(request->cause,IL_CPUTIMER)||CAUSE_IP_GET(request->cause,IL_TIMER)){ + exit(request); } //------------------------------------------------------------- - //----------------------------------------Processor Local Timer - if (CAUSE_IP_GET(request->cause,IL_CPUTIMER)){ /*Future use*/ - PANIC(); + /*With this comment, we mean that the underlying management code + * is related to interrupts raised on lines> = 3. For this reason, + * it is also necessary to identify the specific device that + * generated the interrupt. + */ + int line; + int dev; + if((line = get_interrupting_line(request))<0 || (dev = get_interrupting_device(line))<0){ + PANIC(); /*something bad happens*/ } - //------------------------------------------------------------- - //-----------------------------------------------Interval Timer - if (CAUSE_IP_GET(request->cause,IL_TIMER)){ - scheduler_StateToReady(request); /*Add req to ready queue*/ - scheduler_StateToRunning(); /*Schedule*/ + devreg_t *dev_reg = (devreg_t *) DEV_REG_ADDR(line, dev); + unsigned int dev_status = GET_DEV_STATUS(dev_reg,line); /*status of device*/ + + if(line==IL_TERMINAL){ + handle_irq_terminal(dev_reg); + }else{ + handle_irq_other_dev(dev_reg); + } + + int *sem = &(semdev[GET_SEM_INDEX(dev_reg,line,dev)]); /*sem associated with device*/ + if(++(*sem) <= 0){ /*V on this sem*/ + pcb_t *p = removeBlocked(sem); + if(p!=NULL){ + p->p_s.reg_v0 = dev_status; + /*add process to ready queue*/ + scheduler_AddProcess(p); + } } - //------------------------------------------------------------- + exit(request); +} +int get_interrupting_line(state_t *request){ //-------------------------------------------------Disk Devices - if (CAUSE_IP_GET(request->cause,IL_DISK)){ /*Future use*/ - PANIC(); + if (CAUSE_IP_GET(request->cause,IL_DISK)){ + return IL_DISK; } - //------------------------------------------------------------- - //-------------------------------------------------Tape Devices - if (CAUSE_IP_GET(request->cause,IL_TAPE)){ /*Future use*/ - PANIC(); + if (CAUSE_IP_GET(request->cause,IL_TAPE)){ + return IL_TAPE; } - //------------------------------------------------------------- - //----------------------------------------------Network Devices - if (CAUSE_IP_GET(request->cause,IL_ETHERNET)){ /*Future use*/ - PANIC(); + if (CAUSE_IP_GET(request->cause,IL_ETHERNET)){ + return IL_ETHERNET; } - //------------------------------------------------------------- - //----------------------------------------------Printer Devices - if (CAUSE_IP_GET(request->cause,IL_PRINTER)){ /*Future use*/ - PANIC(); + if (CAUSE_IP_GET(request->cause,IL_PRINTER)){ + return IL_PRINTER; } - //------------------------------------------------------------- - //---------------------------------------------Terminal Devices - if (CAUSE_IP_GET(request->cause,IL_TERMINAL)){ /*Future use*/ - PANIC(); + if (CAUSE_IP_GET(request->cause,IL_TERMINAL)){ + return IL_TERMINAL; } - //------------------------------------------------------------- + return -1; /*error*/ +} - PANIC();/*interrupt not defined*/ -} \ No newline at end of file +int get_interrupting_device(int line){ + for(int i=0;iterm->transm_status)){ + /* gestione del terminale di ricezione */ + dev_reg->term->recv_command = IS_TERM_IN_ERROR(dev_reg->term->recv_status) ? RESET : ACK; + return; + } + /* gestione del terminale di trasmissione */ + dev_reg->term->transm_command = IS_TERM_IN_ERROR(dev_reg->term->transm_status) ? RESET : ACK; +} + +void handle_irq_other_dev(devreg_t *dev_reg){ + dev_reg->dtp->command = IS_DEV_IN_ERROR(dev_reg->dtp->status) ? RESET : ACK; +} + +void exit(state_t *req){ + scheduler_StateToReady(req); /*Add req to ready queue*/ + scheduler_StateToRunning(); /*Schedule*/ +} +//------------------------------------------------------------------