tuck int superHtake_batt_intr(Engine *E, State *S) { if (!interruptible(S)) { return -1; } if (S->step == superHfaststep) { S->superH->SPC = S->PC; } else { drain_pipeline(E, S); /* */ /* Must do this after drain because */ /* executed instruction during drain */ /* might set PC (e.g. a BRA) */ /* */ S->superH->SPC = S->PC; } S->superH->SSR = S->superH->SR; S->superH->SR.BL = 1; S->superH->SR.MD = 1; S->superH->SR.RB = 1; S->superH->INTEVT = BATT_LOW_EXCP_CODE; S->PC = S->superH->VBR + 0x600; return 0; }
// Called at stub *exit* static void handle_exception_init( void ) { // Compact register array again. HAL_SET_GDB_REGISTERS(_hal_registers, ®isters[0]); interruptible(1); }
boost::asynchronous::any_interruptible interruptible_post(typename queue_type::job_type& job, std::size_t prio=0) { boost::shared_ptr<boost::asynchronous::detail::interrupt_state> state = boost::make_shared<boost::asynchronous::detail::interrupt_state>(); boost::shared_ptr<boost::promise<boost::thread*> > wpromise = boost::make_shared<boost::promise<boost::thread*> >(); boost::asynchronous::job_traits<typename queue_type::job_type>::set_posted_time(job); boost::asynchronous::interruptible_job<typename queue_type::job_type,this_type> ijob(job,wpromise,state); m_queue->push(ijob,prio); boost::shared_future<boost::thread*> fu = wpromise->get_future(); boost::asynchronous::interrupt_helper interruptible(fu,state); return boost::asynchronous::any_interruptible(interruptible); }
tuck int superHtake_timer_intr(Engine *E, State *S) { if (!interruptible(S)) { return -1; } /* */ /* Timer interrupts should be in terms of absolute time, not */ /* clock cycles, so that even w/ volt/freq scaling, we will */ /* still get timer interrupts at the same time spacing */ /* */ if ((S->superH->ENABLE_CLK_INTR) && (S->ICLK) && (S->superH->SR.BL == 0) && (S->superH->SR.IMASK < TIMER_FIXED_INTRLEVEL) ) { if (S->step == superHfaststep) { S->superH->SPC = S->PC; } else { drain_pipeline(E, S); /* */ /* Must do this after drain because */ /* executed instruction during drain */ /* might set PC (e.g. a BRA) */ /* */ S->superH->SPC = S->PC; } S->superH->SSR = S->superH->SR; S->superH->SR.BL = 1; S->superH->SR.MD = 1; S->superH->SR.RB = 1; S->superH->INTEVT = TMU0_TUNI0_EXCP_CODE; S->PC = S->superH->VBR + 0x600; S->sleep = 0; } return 0; }
// Called at stub *entry* static void handle_exception_cleanup( void ) { #ifndef CYGPKG_REDBOOT static int orig_registers_set = 0; #endif interruptible(0); // Expand the HAL_SavedRegisters structure into the GDB register // array format. HAL_GET_GDB_REGISTERS(®isters[0], _hal_registers); _registers = ®isters[0]; #ifndef CYGPKG_REDBOOT if (!orig_registers_set) { int i; for (i = 0; i < (sizeof(registers)/sizeof(registers[0])); i++) orig_registers[i] = registers[i]; _registers = &orig_registers[0]; if (__is_breakpoint_function ()) __skipinst (); _registers = ®isters[0]; orig_registers_set = 1; } #endif #ifdef HAL_STUB_PLATFORM_STUBS_FIXUP // Some architectures may need to fix the PC in case of a partial // or fully executed trap instruction. GDB only takes correct action // when the PC is pointing to the breakpoint instruction it set. // // Most architectures would leave PC pointing at the trap // instruction itself though, and so do not need to do anything // special. HAL_STUB_PLATFORM_STUBS_FIXUP(); #endif #ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT // If we continued instead of stepping, when there was a break set // ie. we were stepping within a critical region, clear the break, and // that flag. If we stopped for some other reason, this has no effect. if ( cyg_hal_gdb_running_step ) { cyg_hal_gdb_running_step = 0; cyg_hal_gdb_remove_break(get_register (PC)); } // FIXME: (there may be a better way to do this) // If we hit a breakpoint set by the gdb interrupt stub, make it // seem like an interrupt rather than having hit a breakpoint. cyg_hal_gdb_break = cyg_hal_gdb_remove_break(get_register (PC)); #endif #if defined(HAL_STUB_HW_WATCHPOINT) || defined(HAL_STUB_HW_BREAKPOINT) // For HW watchpoint/breakpoint support, we need to know if we // stopped because of watchpoint or hw break. We do that here // before GDB has a chance to remove the watchpoints and save // the information for later use in building response packets. _hw_stop_reason = HAL_STUB_IS_STOPPED_BY_HARDWARE(_watch_data_addr); #endif }
/* * General purpose routine for passing commands to gdb. All gdb commands * come through here, where they are passed to gdb_command_funnel(). */ void gdb_interface(struct gnu_request *req) { if (!(pc->flags & GDB_INIT)) error(FATAL, "gdb_interface: gdb not initialized?\n"); if (output_closed()) restart(0); if (!req->fp) { req->fp = ((pc->flags & RUNTIME) || (pc->flags2 & ALLOW_FP)) ? fp : CRASHDEBUG(1) ? fp : pc->nullfp; } pc->cur_req = req; pc->cur_gdb_cmd = req->command; if (req->flags & GNU_RETURN_ON_ERROR) { error_hook = gdb_error_hook; if (setjmp(pc->gdb_interface_env)) { pc->last_gdb_cmd = pc->cur_gdb_cmd; pc->cur_gdb_cmd = 0; pc->cur_req = NULL; req->flags |= GNU_COMMAND_FAILED; pc->flags &= ~IN_GDB; return; } } else error_hook = NULL; if (CRASHDEBUG(2)) dump_gnu_request(req, IN_GDB); if (!(pc->flags & DROP_CORE)) SIGACTION(SIGSEGV, restart, &pc->sigaction, NULL); else SIGACTION(SIGSEGV, SIG_DFL, &pc->sigaction, NULL); if (interruptible()) { SIGACTION(SIGINT, pc->gdb_sigaction.sa_handler, &pc->gdb_sigaction, NULL); } else { SIGACTION(SIGINT, SIG_IGN, &pc->sigaction, NULL); SIGACTION(SIGPIPE, SIG_IGN, &pc->sigaction, NULL); } pc->flags |= IN_GDB; gdb_command_funnel(req); pc->flags &= ~IN_GDB; SIGACTION(SIGINT, restart, &pc->sigaction, NULL); SIGACTION(SIGSEGV, SIG_DFL, &pc->sigaction, NULL); if (CRASHDEBUG(2)) dump_gnu_request(req, !IN_GDB); error_hook = NULL; pc->last_gdb_cmd = pc->cur_gdb_cmd; pc->cur_gdb_cmd = 0; pc->cur_req = NULL; }
tuck int superHtake_nic_intr(Engine *E, State *S) { Interrupt *interrupt; if (!interruptible(S)) { return -1; } /* */ /* (PC is incremented at end of step() in pipeline.c) */ /* We need to re-exec instruction which is currently in */ /* ID when we RTE, so save that kids PC! (then do a */ /* ifidflush()). If we are faststeping, then S->PC is */ /* the next instr that we would place into EX and exec. */ /* */ /* i.e., at this point, we are yet to execute instruction */ /* @PC (fastep/step below) so rather than setting SPC */ /* to PC+2, we set it to PC, so that RTE executes the */ /* instr after then one after we caught the interrupt. */ /* */ if (S->step == superHfaststep) { S->superH->SPC = S->PC; } else { drain_pipeline(E, S); /* */ /* Must do this after drain because */ /* executed instruction during drain */ /* might set PC (e.g. a BRA) */ /* */ S->superH->SPC = S->PC; } S->superH->SSR = S->superH->SR; S->superH->SR.BL = 1; S->superH->SR.MD = 1; S->superH->SR.RB = 1; S->PC = S->superH->VBR + 0x600; S->sleep = 0; interrupt = (Interrupt *)pic_intr_dequeue(E, S, S->superH->nicintrQ); if (interrupt == NULL) { sfatal(E, S, "We supposedly had an interrupt, but nothing was queued!"); } /* */ /* The value field, which in the case of NIC, specifies */ /* which interface the interrupt was generated by. The */ /* apps. interpret exception codes offset from base as */ /* the interface number (well, you know what i mean...) */ /* */ switch (interrupt->type) { case NIC_RXOK_INTR: { S->superH->INTEVT = (NIC_RX_EXCP_CODE + interrupt->value); break; } case NIC_TXOK_INTR: { S->superH->INTEVT = (NIC_TX_EXCP_CODE + interrupt->value); break; } case NIC_ADDRERR_INTR: { S->superH->INTEVT = (NIC_ADDR_EXCP_CODE + interrupt->value); break; } case NIC_FRAMEERR_INTR: { S->superH->INTEVT = (NIC_FRAME_EXCP_CODE + interrupt->value); break; } case NIC_COLLSERR_INTR: { S->superH->INTEVT = (NIC_COLLS_EXCP_CODE + interrupt->value); break; } case NIC_CSENSEERR_INTR: { S->superH->INTEVT = (NIC_CSENSE_EXCP_CODE + interrupt->value); break; } case NIC_RXOVRRUNERR_INTR: { S->superH->INTEVT = (NIC_RXOVRRUN_EXCP_CODE + interrupt->value); break; } case NIC_RXUNDRRUNERR_INTR: { S->superH->INTEVT = (NIC_RXUNDRRUN_EXCP_CODE + interrupt->value); break; } case NIC_TXOVRRUNERR_INTR: { S->superH->INTEVT = (NIC_TXOVRRUN_EXCP_CODE + interrupt->value); break; } case NIC_TXUNDRRUNERR_INTR: { S->superH->INTEVT = (NIC_TXUNDRRUN_EXCP_CODE + interrupt->value); break; } case NIC_CSUMERR_INTR: { S->superH->INTEVT = (NIC_CSUM_EXCP_CODE + interrupt->value); break; } default: { mprint(E, S, nodeinfo, "Received interrupt type [%d]\n", interrupt->type); sfatal(E, S, "Unknown interrupt type!"); } } mfree(E, interrupt, "Interrupt *interrupt in machine-hitachi-sh.c"); return 0; }