/* Add cycles to the serial transfer, * used to ensure when using internal clock, * data is transfered at the correct clock speed */ void inc_serial_cycles(unsigned cycles) { if (transfer_in_progress && internal_clock) { cur_cycles += cycles; if (cur_cycles >= (GB_CLOCK_SPEED_HZ / gb_io_freq)) { cur_cycles = 0; *recieved_location = transfer_int(data_to_send); raise_interrupt(IO_INT); *control &= (0x7F); transfer_in_progress = 0; internal_clock = 0; } } // Poll external transfer if (transfer_in_progress && !internal_clock) { uint8_t result; int complete; if ((complete = transfer_ext(data_to_send, &result))) { *recieved_location = result; raise_interrupt(IO_INT); *control &= (0x7F); transfer_in_progress = 0; } } }
static void test_interrupts () { /* processor interrupts are usualy fatal - can't recover easy! */ arch_register_interrupt_handler ( 0, processor_irq_handler ); arch_register_interrupt_handler ( 5, processor_irq_handler ); arch_register_interrupt_handler ( 10, processor_irq_handler ); arch_register_interrupt_handler ( 15, processor_irq_handler ); /* interrupts generated outside processor */ arch_register_interrupt_handler ( 32, device_irq_handler ); arch_register_interrupt_handler ( 35, device_irq_handler ); arch_register_interrupt_handler ( 37, device_irq_handler ); arch_register_interrupt_handler ( 39, device_irq_handler ); /* irq number outside allowed range */ //arch_register_interrupt_handler ( 60, device_irq_handler ); /* raise a few interrupts (comment/uncomment for testing) */ //raise_interrupt ( 0 ); //raise_interrupt ( 1 ); //raise_interrupt ( 5 ); //raise_interrupt ( 7 ); //raise_interrupt ( 10 ); //raise_interrupt ( 20 ); raise_interrupt ( 32 ); raise_interrupt ( 35 ); raise_interrupt ( 38 ); }
int segm_fault () { #if TEST == 1 printf ( "\nInterrupt test >>>\n" ); arch_register_interrupt_handler ( SOFTWARE_INTERRUPT, test1 ); arch_register_interrupt_handler ( SOFTWARE_INTERRUPT, test1 ); raise_interrupt ( SOFTWARE_INTERRUPT ); printf ( "Interrupt test <<<\n\n" ); #else unsigned int *p; unsigned int i, j=0; printf ( "Example program: [%s:%s]\n%s\n\n", __FILE__, __FUNCTION__, segm_fault_PROG_HELP ); printf ( "Before segmentation fault\n" ); for ( i = 16; i < 32; i++ ) { p = (unsigned int *) (1 << i); printf ( "[%x]=%d\n", p, *p ); j+= *p; } printf ( "After expected segmentation fault, j=%d\n", j ); #endif return 0; }
static void Monitor_raise_interrupt ( struct mon_t *mon, unsigned int ivector ) { struct user_regs_struct saved_uregs; ASSERT ( mon != NULL ); check_stack_permission_for_interrupt ( mon ); check_idt_permission ( mon, ivector ); saved_uregs = mon->regs->user; /* [STAT] */ assert ( mon->regs->user.eip <= VM_PMEM_BASE ); raise_interrupt ( mon->regs, ivector, &Monitor_pushl, &Monitor_laddr_to_raddr ); /* [STAT] */ mon->stat.nr_interrupts[ivector]++; mon->stat.kernel_state = ivector; if ( ivector == IVECTOR_SYSCALL ) { save_syscall_state ( &mon->guest_state, mon, &saved_uregs ); } }
// An external process can send interrupts to the emulator by writing to a // named pipe. Poll the pipe to determine if any messages are pending. If // so, call into the core to dispatch. void check_interrupt_pipe(struct core *core) { int result; char interrupt_id; if (recv_interrupt_fd < 0) return; result = can_read_file_descriptor(recv_interrupt_fd); if (result == 0) return; if (result < 0) { perror("check_interrupt_pipe: select failed"); exit(1); } if (read(recv_interrupt_fd, &interrupt_id, 1) < 1) { perror("check_interrupt_pipe: read failed"); exit(1); } if (interrupt_id > 16) { fprintf(stderr, "Received invalidate interrupt ID %d\n", interrupt_id); return; // Ignore invalid interrupt IDs } raise_interrupt(core, 1 << interrupt_id); }
void helper_into(CPUX86State *env, int next_eip_addend) { int eflags; eflags = cpu_cc_compute_all(env, CC_OP); if (eflags & CC_O) { raise_interrupt(env, EXCP04_INTO, 1, 0, next_eip_addend); } }
void trigger_key(u32 key) { u32 p1_cnt = io_registers[REG_P1CNT]; if((p1_cnt >> 14) & 0x01) { u32 key_intersection = (p1_cnt & key) & 0x3FF; if(p1_cnt >> 15) { if(key_intersection == (p1_cnt & 0x3FF)) raise_interrupt(IRQ_KEYPAD); } else { if(key_intersection) raise_interrupt(IRQ_KEYPAD); } }
int raise(int which) { _Sigfun *fn; unsigned int ptr; if (which < 0 || which >= _NSIG) return -1; if (which <= _MAX_REAL_SIG) { return raise_interrupt((interrupt_kind)which, which, 0, 0, 0); } fn = _vector_table[which]; if ((fn == 0) || (fn == SIG_IGN)) return 0; ptr = (unsigned int)fn; if ((ptr & 1) == 0) _vector_table[which] = 0; ptr &= ~1; fn = (_Sigfun *)ptr; (*fn)(which); return 0; }
/** Abort a job. This can be used as callback for \c task_call_with_context(). */ static void irq_handler( corecontext_t* context, void* arg) { struct JOB_IRQ* irq = arg; UNUSED_PARAM(corecontext_t*, context); HQASSERT(irq->job != NULL, "NULL job pointer"); task_group_cancel(irq->job->task_group, irq->error); /* Cancel first so that the error propagates. */ if (irq->job->state == CORE_JOB_RUNNING) { /* Raise interrupt for interpreter if the job is still running. */ if (irq->error == TIMEOUT) raise_timeout(); else raise_interrupt(); } }
void hardware_step(uint16_t where) { uint16_t arg; char buf[32]; switch(hardware[where].type) { case HARDWARE_BUILTIN: hardware[where].hw.builtin->step(); break; case HARDWARE_MODULE: if (readline_async(hardware[where].hw.module->rx, buf, 32)) { if (strncmp(buf, "int", 3) == 0) { DBGPRINT("from module: %s", buf); sscanf(buf, "int %hu", &arg); raise_interrupt(arg); } else { // TODO bad async msg, shutdown module? } } break; default: break; } }
void helper_raise_interrupt(CPUX86State *env, int intno, int next_eip_addend) { raise_interrupt(env, intno, 1, 0, next_eip_addend); }