/* Queue a division exception. */ enum frv_dtt frvbf_division_exception (SIM_CPU *current_cpu, enum frv_dtt dtt, int target_index, int non_excepting) { /* If there was an overflow and it is masked, then record it in ISR.AEXC. */ USI isr = GET_ISR (); if ((dtt & FRV_DTT_OVERFLOW) && GET_ISR_EDE (isr)) { dtt &= ~FRV_DTT_OVERFLOW; SET_ISR_AEXC (isr); SET_ISR (isr); } if (dtt != FRV_DTT_NO_EXCEPTION) { if (non_excepting) { /* Non excepting instruction, simply set the NE flag for the target register. */ SI NE_flags[2]; GET_NE_FLAGS (NE_flags, H_SPR_GNER0); SET_NE_FLAG (NE_flags, target_index); SET_NE_FLAGS (H_SPR_GNER0, NE_flags); } else frv_queue_division_exception_interrupt (current_cpu, dtt); } return dtt; }
/* Record the state of a division exception in the ISR. */ static void set_isr_exception_fields ( SIM_CPU *current_cpu, struct frv_interrupt_queue_element *item ) { USI isr = GET_ISR (); int dtt = GET_ISR_DTT (isr); dtt |= item->u.dtt; SET_ISR_DTT (isr, dtt); SET_ISR (isr); }
static SI fr400_check_readwrite_address (SIM_CPU *current_cpu, SI address, int align_mask) { if (address & align_mask) { /* Make sure that this exception is not masked. */ USI isr = GET_ISR (); if (! GET_ISR_EMAM (isr)) { /* Bad alignment causes a data_access_error on fr400. */ frv_queue_data_access_error_interrupt (current_cpu, address); } address &= ~align_mask; } /* Nothing to check. */ return address; }
struct frv_interrupt_queue_element * frv_queue_mem_address_not_aligned_interrupt (SIM_CPU *current_cpu, USI addr) { struct frv_interrupt_queue_element *new_element; USI isr = GET_ISR (); /* Make sure that this exception is not masked. */ if (GET_ISR_EMAM (isr)) return NULL; /* Queue the interrupt. */ new_element = frv_queue_program_interrupt (current_cpu, FRV_MEM_ADDRESS_NOT_ALIGNED); new_element->eaddress = addr; new_element->u.data_written = frv_interrupt_state.data_written; frv_interrupt_state.data_written.length = 0; return new_element; }
/************************ * * hwt_read * * Stop hardware timer and read time elapsed since last start. * * u_long hwt_read(smc) ; * In * smc - A pointer to the SMT Context structure. * Out * The elapsed time since last start in units of 16us. * ************************/ u_long hwt_read(struct s_smc *smc) { u_short tr ; u_long is ; if (smc->hw.timer_activ) { hwt_stop(smc) ; tr = (u_short)((inpd(ADDR(B2_TI_VAL))/200) & 0xffff) ; is = GET_ISR() ; /* Check if timer expired (or wraparound). */ if ((tr > smc->hw.t_start) || (is & IS_TIMINT)) { hwt_restart(smc) ; smc->hw.t_stop = smc->hw.t_start ; } else smc->hw.t_stop = smc->hw.t_start - tr ; } <<<<<<< HEAD
void fddi_isr(struct s_smc *smc) { u_long is ; /* ISR source */ u_short stu, stl ; SMbuf *mb ; #ifdef USE_BREAK_ISR int force_irq ; #endif #ifdef ODI2 if (smc->os.hwm.rx_break) { mac_drv_fill_rxd(smc) ; if (smc->hw.fp.rx_q[QUEUE_R1].rx_used > 0) { smc->os.hwm.rx_break = 0 ; process_receive(smc) ; } else { smc->os.hwm.detec_count = 0 ; smt_force_irq(smc) ; } } #endif smc->os.hwm.isr_flag = TRUE ; #ifdef USE_BREAK_ISR force_irq = TRUE ; if (smc->os.hwm.leave_isr) { smc->os.hwm.leave_isr = FALSE ; process_receive(smc) ; } #endif while ((is = GET_ISR() & ISR_MASK)) { NDD_TRACE("CH0B",is,0,0) ; DB_GEN("ISA = 0x%x",is,0,7) ; if (is & IMASK_SLOW) { NDD_TRACE("CH1b",is,0,0) ; if (is & IS_PLINT1) { /* PLC1 */ plc1_irq(smc) ; } if (is & IS_PLINT2) { /* PLC2 */ plc2_irq(smc) ; } if (is & IS_MINTR1) { /* FORMAC+ STU1(U/L) */ stu = inpw(FM_A(FM_ST1U)) ; stl = inpw(FM_A(FM_ST1L)) ; DB_GEN("Slow transmit complete",0,0,6) ; mac1_irq(smc,stu,stl) ; } if (is & IS_MINTR2) { /* FORMAC+ STU2(U/L) */ stu= inpw(FM_A(FM_ST2U)) ; stl= inpw(FM_A(FM_ST2L)) ; DB_GEN("Slow receive complete",0,0,6) ; DB_GEN("stl = %x : stu = %x",stl,stu,7) ; mac2_irq(smc,stu,stl) ; } if (is & IS_MINTR3) { /* FORMAC+ STU3(U/L) */ stu= inpw(FM_A(FM_ST3U)) ; stl= inpw(FM_A(FM_ST3L)) ; DB_GEN("FORMAC Mode Register 3",0,0,6) ; mac3_irq(smc,stu,stl) ; } if (is & IS_TIMINT) { /* Timer 82C54-2 */ timer_irq(smc) ; #ifdef NDIS_OS2 force_irq_pending = 0 ; #endif /* * out of RxD detection */ if (++smc->os.hwm.detec_count > 4) { /* * check out of RxD condition */ process_receive(smc) ; } } if (is & IS_TOKEN) { /* Restricted Token Monitor */ rtm_irq(smc) ; } if (is & IS_R1_P) { /* Parity error rx queue 1 */ /* clear IRQ */ outpd(ADDR(B4_R1_CSR),CSR_IRQ_CL_P) ; SMT_PANIC(smc,HWM_E0004,HWM_E0004_MSG) ; } if (is & IS_R1_C) { /* Encoding error rx queue 1 */ /* clear IRQ */ outpd(ADDR(B4_R1_CSR),CSR_IRQ_CL_C) ; SMT_PANIC(smc,HWM_E0005,HWM_E0005_MSG) ; } if (is & IS_XA_C) { /* Encoding error async tx q */ /* clear IRQ */ outpd(ADDR(B5_XA_CSR),CSR_IRQ_CL_C) ; SMT_PANIC(smc,HWM_E0006,HWM_E0006_MSG) ; } if (is & IS_XS_C) { /* Encoding error sync tx q */ /* clear IRQ */ outpd(ADDR(B5_XS_CSR),CSR_IRQ_CL_C) ; SMT_PANIC(smc,HWM_E0007,HWM_E0007_MSG) ; } } /* * Fast Tx complete Async/Sync Queue (BMU service) */ if (is & (IS_XS_F|IS_XA_F)) { DB_GEN("Fast tx complete queue",0,0,6) ; /* * clear IRQ, Note: no IRQ is lost, because * we always service both queues */ outpd(ADDR(B5_XS_CSR),CSR_IRQ_CL_F) ; outpd(ADDR(B5_XA_CSR),CSR_IRQ_CL_F) ; mac_drv_clear_txd(smc) ; llc_restart_tx(smc) ; } /* * Fast Rx Complete (BMU service) */ if (is & IS_R1_F) { DB_GEN("Fast receive complete",0,0,6) ; /* clear IRQ */ #ifndef USE_BREAK_ISR outpd(ADDR(B4_R1_CSR),CSR_IRQ_CL_F) ; process_receive(smc) ; #else process_receive(smc) ; if (smc->os.hwm.leave_isr) { force_irq = FALSE ; } else { outpd(ADDR(B4_R1_CSR),CSR_IRQ_CL_F) ; process_receive(smc) ; } #endif } #ifndef NDIS_OS2 while ((mb = get_llc_rx(smc))) { smt_to_llc(smc,mb) ; } #else if (offDepth) post_proc() ; while (!offDepth && (mb = get_llc_rx(smc))) { smt_to_llc(smc,mb) ; } if (!offDepth && smc->os.hwm.rx_break) { process_receive(smc) ; } #endif if (smc->q.ev_get != smc->q.ev_put) { NDD_TRACE("CH2a",0,0,0) ; ev_dispatcher(smc) ; } #ifdef NDIS_OS2 post_proc() ; if (offDepth) { /* leave fddi_isr because */ break ; /* indications not allowed */ } #endif #ifdef USE_BREAK_ISR if (smc->os.hwm.leave_isr) { break ; /* leave fddi_isr */ } #endif /* NOTE: when the isr is left, no rx is pending */ } /* end of interrupt source polling loop */ #ifdef USE_BREAK_ISR if (smc->os.hwm.leave_isr && force_irq) { smt_force_irq(smc) ; } #endif smc->os.hwm.isr_flag = FALSE ; NDD_TRACE("CH0E",0,0,0) ; }