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

Commit

Permalink
Implementata parte della gestione degli interrupt #20
Browse files Browse the repository at this point in the history
  • Loading branch information
BI-612 committed May 1, 2020
1 parent ad1fef5 commit 78d7561
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 50 deletions.
60 changes: 59 additions & 1 deletion include/umps/umpsconst.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
#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<<i)) != 0)

/* We are 8 type of interrupt lines. But, only 5
* lines are related to devices.
*/
#define DEV_ONLY (N_IL-3)
#define SEM_DEV_N ((DEV_ONLY+1)*N_DEV_PER_IL)

//
#define GET_SEM_OFFSET(dev_reg,line) (line!=IL_TERMINAL ? (0) : (IS_TERM_READY(dev_reg->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))


20 changes: 10 additions & 10 deletions src/handler/uarm/handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
123 changes: 84 additions & 39 deletions src/handler/umps/handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include <handler/shared.h>
#include <scheduler/scheduler.h>

extern int semdev[SEM_DEV_N]; // la vera struttura dati sarà nell init.c

// Syscall-Breakpoint Handler
//---------------------------------------------------------------
void Handler_SysCall(void){
Expand Down Expand Up @@ -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*/
}
int get_interrupting_device(int line){
for(int i=0;i<N_DEV_PER_IL;i++){
if(IS_IRQ_RAISED_FROM_I(line,i)){
return i;
}
}
return -1; /*error*/
}

void handle_irq_terminal(devreg_t *dev_reg){
if(IS_TERM_READY(dev_reg->term->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*/
}
//------------------------------------------------------------------

0 comments on commit 78d7561

Please sign in to comment.