Skip to content
This repository has been archived by the owner on Nov 2, 2022. It is now read-only.

Commit

Permalink
Gestione multi interrupt; #20
Browse files Browse the repository at this point in the history
  • Loading branch information
BI-612 committed May 7, 2020
1 parent 0f46cc7 commit 43471dd
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 29 deletions.
6 changes: 6 additions & 0 deletions include/handler/shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ int get_interrupting_line(word cause);
*/
int get_interrupting_device(int line);

/**
* @brief Gestore per interrupt device. Richiama i metodi sottostanti in base
* al parametro line
*/
void handle_irq(unsigned int line, unsigned int dev);

/**
* @brief Gestione per i terminali di ricezione e trasmissione. Se è presente un codice di errore nello status del terminale
* scrive nel command register il comando RESET, altrimenti scrive il comando ACK
Expand Down
5 changes: 5 additions & 0 deletions include/umps/umpsconst.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,8 @@
#define INTERVAL_TIMER_OFF (~INTERVAL_TIMER_ON)

#define CAUSE_IP_GET(cause, line) ((cause&CAUSE_IP(line)) != 0)


#define CDEV_BITMAP_DEV_ADDR(line,dev) (CDEV_BITMAP_ADDR(line) + (dev))
#define CDEV_BITMAP_DEV(line,dev) *((unsigned int *)CDEV_BITMAP_DEV_ADDR(line,dev))
#define IRQ_FROM(line,dev) (CDEV_BITMAP_DEV(line,dev) == 1U)
2 changes: 1 addition & 1 deletion src/handler/shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,5 +274,5 @@ void handle_irq_terminal(devreg_t *dev_reg){
}

void handle_irq_other_dev(devreg_t *dev_reg){
dev_reg->dtp.command = IS_DEV_IN_ERROR( (dev_reg->dtp.status) ) ? DEV_CMD_RESET : DEV_CMD_ACK;
dev_reg->dtp.command = IS_DEV_IN_ERROR(dev_reg->dtp.status) ? DEV_CMD_RESET : DEV_CMD_ACK;
}
61 changes: 33 additions & 28 deletions src/handler/umps/handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void Handler_SysCall(void){
break;
default:
PANIC();
break;
break; // (from sds) non necessario; è l'ultimo case
}
scheduler_schedule( FALSE ); /* fin qui può essere accaduto di tutto al processo attuale, quindi "decide" lo scheduler */
}
Expand Down Expand Up @@ -74,7 +74,7 @@ void Handler_Trap(void) {
if( area != NULL ) {
LDST( area );
}
PANIC(); /*Questa eccezione è disabilitata!*/
PANIC(); /*Questa eccezione è disabilitata!*/
}
//----------------------------------------------------------------

Expand All @@ -100,20 +100,18 @@ void Handler_Interrupt(void) {
PANIC(); /*REQ ERROR*/
}

//----------------------------------------------Inter-processor
if(CAUSE_IP_GET(cause, IL_IPI)){
PANIC(); /*NOT SUPPORTED*/
//----------------Inter-processor irq/Processor Local Timer irq
if(CAUSE_IP_GET(cause, IL_IPI) || CAUSE_IP_GET(cause, IL_CPUTIMER)){
PANIC(); /*NOT USED*/
}
//-------------------------------------------------------------

scheduler_UpdateContext(request); /* update context */

//--------------------------Processor Local Timer/Interval Timer
if(CAUSE_IP_GET(cause, IL_CPUTIMER)){
scheduler_schedule(FALSE);
}
int irq_served = FALSE;
int force_switch = FALSE;
//-------------------------------------------Interval Timer irq
if(CAUSE_IP_GET(cause, IL_TIMER)){
scheduler_schedule(TRUE);
force_switch = irq_served = TRUE;
}
//-------------------------------------------------------------

Expand All @@ -122,25 +120,32 @@ void Handler_Interrupt(void) {
* it is also necessary to identify the specific device that
* generated the interrupt.
*/
int line;
int dev;
if((line = get_interrupting_line(cause))<0 || (dev = get_interrupting_device(line))<0){
PANIC(); /*something bad happens*/
unsigned int dev_line;
unsigned int dev;
for(dev_line=0; dev_line<N_EXT_IL;dev_line++){
for(dev=0; dev_line<N_DEV_PER_IL;dev++){
if(IRQ_FROM(dev_line,dev)){
handle_irq(dev_line+3,dev);
irq_served = TRUE;
}
}
}
if(!irq_served){
PANIC(); /*irq but no interrupt served?*/
}

devreg_t *dev_reg = (devreg_t *) DEV_REG_ADDR(line, dev);
unsigned int dev_status = GET_DEV_STATUS(dev_reg,line); /*status of device*/
scheduler_schedule(force_switch);
}

if(line==IL_TERMINAL){
handle_irq_terminal(dev_reg);
}else{
handle_irq_other_dev(dev_reg);
}
void handle_irq(unsigned int line, unsigned int dev){
devreg_t *dev_reg = (devreg_t *) DEV_REG_ADDR(line, dev);
word dev_status = GET_DEV_STATUS(dev_reg,line); /*status of device*/

(line==IL_TERMINAL) ? handle_irq_terminal(dev_reg) : handle_irq_other_dev(dev_reg);

int *sem = device_GetSem( line, dev, GET_SEM_OFFSET(dev_reg, line) ); /*sem associated with device*/
pcb_t *p = semaphore_V( sem );
if( p != NULL ){
int *sem = device_GetSem(line, dev, GET_SEM_OFFSET(dev_reg, line)); /*sem associated with device*/
pcb_t *p = semaphore_V(sem);
if(p != NULL){
p->p_s.reg_v0 = dev_status;
}
scheduler_schedule(FALSE);
}
}

0 comments on commit 43471dd

Please sign in to comment.