void ttyinit(int dev) { int baseport, ret; /* initialize baseport and return val variable for queue operations*/ struct tty *tty; /* ptr to tty software params/data block */ baseport = devtab[dev].dvbaseport; /* pick up hardware addr */ tty = (struct tty *)devtab[dev].dvdata; /* and software params struct */ cli(); if (baseport == COM1_BASE) { /* arm interrupts by installing interrupt vector address */ set_intr_gate(COM1_IRQ+IRQ_TO_INT_N_SHIFT, &irq4inthand); pic_enable_irq(COM1_IRQ); } else if (baseport == COM2_BASE) { /* arm interrupts by installing interrupt vector address */ set_intr_gate(COM2_IRQ+IRQ_TO_INT_N_SHIFT, &irq3inthand); pic_enable_irq(COM2_IRQ); } else { kprintf("Bad TTY device table entry, dev %d\n", dev); return; /* give up */ } tty->echoflag = 1; /* default to echoing */ ret = init_queue((tty->rqu), MAXQ); /* init RX queue */ ret = init_queue((tty->tqu), MAXQ); /* init TX queue */ outpt(baseport+UART_IER, UART_IER_RDI|UART_IER_THRI); /* enable interrupts on receiver and transmitter */ }
int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) { if (irq >= SYS_IRQS) { printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__, irq, devname); return -ENXIO; } if (!(irq_list[irq].flags & IRQ_FLG_STD)) { if (irq_list[irq].flags & IRQ_FLG_LOCK) { printk("%s: IRQ %d from %s is not replaceable\n", __FUNCTION__, irq, irq_list[irq].devname); return -EBUSY; } if (flags & IRQ_FLG_REPLACE) { printk("%s: %s can't replace IRQ %d from %s\n", __FUNCTION__, devname, irq, irq_list[irq].devname); return -EBUSY; } } irq_list[irq].handler = handler; irq_list[irq].flags = flags; irq_list[irq].dev_id = dev_id; irq_list[irq].devname = devname; pic_enable_irq(irq); return 0; }
void enable_irq(unsigned int irq) { if (irq >= SYS_IRQS) { printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq); return; } pic_enable_irq(irq); }
void bootloader_apic_calibrate_timer(void) { t_ia32_gate gate; t_sint32 t1; t_sint32 t2; /* * 1) */ apic_write(APIC_REG_DIV, 10); apic_write(APIC_REG_TIMER_CONF, 1 << 16); /* * 2) */ apic_write(APIC_REG_TIMER, 1000000000); /* * 3) */ gate.offset = (t_uint32)bootloader_apic_calibrate_tick; gate.segsel = IA32_PMODE_BOOTLOADER_CS << 3; gate.privilege = 0; gate.type = ia32_type_gate_interrupt; idt_add_gate(NULL, 32, gate); pit_init(200); pic_enable_irq(0); ticks = 0; t1 = apic_read(APIC_REG_COUNT); while (ticks < 100) ; pic_disable_irq(0); t2 = apic_read(APIC_REG_COUNT); /* * 4) */ timeref = (t1 - t2); }
void kb_init() { g_initial_ack_received = false; // Get scan-code info g_current_set = sc_get_set_1(); reset_map(); // Enable the keyboard pic_enable_irq(pic_irq_keyboard); OUTB(0x60, 0xF4); // Enable on the encoder OUTB(0x64, 0xAE); // Enable on the controller interrupt_receive(IRQ_1, kb_handle_interrupt); }
void gdb_pc_com_init(int com_port, struct termios *com_params) { int com_irq = com_port & 1 ? 4 : 3; /* Tell the generic serial GDB code how to send and receive characters. */ gdb_serial_recv = gdb_cons_getchar; gdb_serial_send = gdb_cons_putchar; gdb_com_port = com_port; /* Tell the GDB proxy trap handler to use the serial stub. */ gdb_signal = gdb_serial_signal; /* * Stick in gdb's special trap handler. * This gets called before base_trap_handlers is consulted. * If it returns zero, the normal handler is circumvented entirely; * if it returns nonzero, the normal handler runs next. */ base_trap_gdb_handler = gdb_trap_ss; /* * Initialize the serial port. * If no com_params were specified by the caller, * then default to base_raw_termios. * (If we just passed through the NULL, * then com_cons_init would default to base_cooked_termios, * which messes up the GDB remote debugging protocol.) */ if (com_params == 0) com_params = &base_raw_termios; com_cons_init(com_port, com_params); #ifdef KNIT set_irq_handler(com_irq,gdb_pc_com_intr); com_cons_enable_receive_interrupt(com_port); #else /* Hook the COM port's hardware interrupt. The com_cons itself uses only polling for communication; the interrupt is only used to allow the remote debugger to stop us at any point, e.g. when the user presses CTRL-C. */ fill_irq_gate(com_irq, (unsigned)gdb_pc_com_intr, KERNEL_CS, ACC_PL_K); /* Enable the COM port interrupt. */ com_cons_enable_receive_interrupt(com_port); pic_enable_irq(com_irq); #endif }
error_t i8042_initialize(void) { /* input buffer not empty */ while (cpu_inb(I8042_PORT_STATUS) & I8042_BIT_IN_FULL) ; /* self test command */ cpu_outb(I8042_PORT_CMD, I8042_CMD_SELF_TEST); while (!(cpu_inb(I8042_PORT_STATUS) & I8042_BIT_OUT_FULL)) ; if (cpu_inb(I8042_PORT_OUT) != 0x55) { BUG(); return ERROR_FAILURE; } /* test interface command */ cpu_outb(I8042_PORT_CMD, I8042_CMD_IF_TEST); while (!(cpu_inb(I8042_PORT_STATUS) & I8042_BIT_OUT_FULL)) ; if (cpu_inb(I8042_PORT_OUT) != 0x00) { BUG(); return ERROR_FAILURE; } /* enable i8042 controller */ cpu_outb(I8042_PORT_CMD, I8042_CMD_KBD_ENABLE); while (!(cpu_inb(I8042_PORT_STATUS) & I8042_BIT_OUT_FULL)) ; /* clear output buffer */ cpu_inb(I8042_PORT_OUT); /* enable interrupt */ serial_printl("enabling interrupt\n"); pic_enable_irq(1, on_interrupt); return ERROR_SUCCESS; }
/* initialize */ error_t rtl8139_initialize(net_dev_t** res) { rtl8139_dev_t* dev; pci_dev_t* pci; error_t error; *res = NULL; /* find the pci device */ pci = pci_dev_find_rtl8139(); if (is_null(pci)) return ERROR_NOT_FOUND; #if !defined(USE_APIC) pic_enable_irq(0xb, rtl8139_handle_interrupt); #endif /* allocate private data */ dev = rtl8139_dev_new(pci); if (dev == NULL) return ERROR_NO_MEMORY; /* initialize the device */ if (rtl8139_dev_initialize(dev)) return ERROR_FAILURE; /* allocate new device */ error = net_dev_create(&g_device, dev); if (error_is_failure(error)) return error; g_device->send = rtl8139_send; g_device->get_addr = rtl8139_get_addr; g_device->set_addr = rtl8139_set_addr; *res = g_device; return ERROR_SUCCESS; }
void keyboard_enable_irq(void) { pic_enable_irq(KEYBOARD_IRQ_NUM); }
// the kernel bootstrap routine PUBLIC void kernel_thread_t::bootstrap() { // Initializations done -- helping_lock_t can now use helping lock helping_lock_t::threading_system_active = true; // // set up my own thread control block // state_change (0, Thread_running); sched()->set_prio (config::kernel_prio); sched()->set_mcp (config::kernel_mcp); sched()->set_timeslice (config::default_time_slice); sched()->set_ticks_left (config::default_time_slice); present_next = present_prev = this; ready_next = ready_prev = this; // // set up class variables // for (int i = 0; i < 256; i++) prio_next[i] = prio_first[i] = 0; prio_next[config::kernel_prio] = prio_first[config::kernel_prio] = this; prio_highest = config::kernel_prio; timeslice_ticks_left = config::default_time_slice; timeslice_owner = this; // // install our slow trap handler // nested_trap_handler = base_trap_handler; base_trap_handler = thread_handle_trap; // // initialize FPU // set_ts(); // FPU ops -> exception // // initialize interrupts // irq_t::lookup(2)->alloc(this, false); // reserve cascade irq irq_t::lookup(8)->alloc(this, false); // reserve timer irq pic_enable_irq(2); // allow cascaded irqs // set up serial console if (! strstr(kmem::cmdline(), " -I-") && !strstr(kmem::cmdline(), " -irqcom")) { int com_port = console::serial_com_port; int com_irq = com_port & 1 ? 4 : 3; irq_t::lookup(com_irq)->alloc(this, false); // the remote-gdb interrupt pic_enable_irq(com_irq); // for some reason, we have to re-enable the com irq here if (config::serial_esc) com_cons_enable_receive_interrupt(); } // initialize the profiling timer bool user_irq0 = strstr(kmem::cmdline(), "irq0"); if (config::profiling) { if (user_irq0) { kdb_ke("options `-profile' and `-irq0' don't mix " "-- disabling `-irq0'"); } irq_t::lookup(0)->alloc(this, false); profile::init(); if (strstr(kmem::cmdline(), " -profstart")) profile::start(); } else if (! user_irq0) irq_t::lookup(0)->alloc(this, false); // reserve irq0 even though // we don't use it // // set up timer interrupt (~ 1ms) // while (rtcin(RTC_STATUSA) & RTCSA_TUP) ; // wait till RTC ready rtcout(RTC_STATUSA, RTCSA_DIVIDER | RTCSA_1024); // 1024 Hz // set up 1024 Hz interrupt rtcout(RTC_STATUSB, rtcin(RTC_STATUSB) | RTCSB_PINTR | RTCSB_SQWE); rtcin(RTC_INTR); // reset pic_enable_irq(8); // allow this interrupt // // set PCE-Flag in CR4 to enable read of performace measurement counters // in usermode. PMC were introduced in Pentium MMX and PPro processors. // #ifndef CPUF_MMX #define CPUF_MMX 0x00800000 #endif if(strncmp(cpu.vendor_id, "GenuineIntel", 12) == 0 && (cpu.family == CPU_FAMILY_PENTIUM_PRO || cpu.feature_flags & CPUF_MMX)) { set_cr4(get_cr4() | CR4_PCE); } // // allow the boot task to create more tasks // for (unsigned i = config::boot_taskno + 1; i < space_index_t::max_space_number; i++) { check(space_index_t(i).set_chief(space_index(), space_index_t(config::boot_taskno))); } // // create sigma0 // // sigma0's chief is the boot task space_index_t(config::sigma0_id.id.task). set_chief(space_index(), space_index_t(config::sigma0_id.id.chief)); sigma0 = new space_t(config::sigma0_id.id.task); sigma0_thread = new (&config::sigma0_id) thread_t (sigma0, &config::sigma0_id, config::sigma0_prio, config::sigma0_mcp); // push address of kernel info page to sigma0's stack vm_offset_t esp = kmem::info()->sigma0_esp; * reinterpret_cast<vm_offset_t*>(kmem::phys_to_virt(--esp)) = kmem::virt_to_phys(kmem::info()); sigma0_thread->initialize(kmem::info()->sigma0_eip, esp, 0, 0); // // create the boot task // // the boot task's chief is the boot task itself space_index_t(config::boot_id.id.task). set_chief(space_index(), space_index_t(config::boot_id.id.chief)); space_t *boot = new space_t(config::boot_id.id.task); thread_t *boot_thread = new (&config::boot_id) thread_t (boot, &config::boot_id, config::boot_prio, config::boot_mcp); boot_thread->initialize(0x200000, 0x200000, sigma0_thread, 0); // // the idle loop // for (;;) { // printf("I"); sti(); // enable irqs, otherwise idling is fatal if (config::hlt_works_ok) asm("hlt"); // stop the CPU, waiting for an int while (ready_next != this) // are there any other threads ready? schedule(); } }
/* * Recalculate the interrupt masks from scratch. * We could code special registry and deregistry versions of this function that * would be faster, but the code would be nastier, and we don't expect this to * happen very much anyway. */ static void intr_calculatemasks(void) { imask_t newmask[NIPL]; struct intr_source *is; struct intrhand *ih; int irq; for (u_int ipl = IPL_NONE; ipl < NIPL; ipl++) { newmask[ipl] = 0; } /* First, figure out which ipl each IRQ uses. */ for (irq = 0, is = intrsources; irq < NVIRQ; irq++, is++) { for (ih = is->is_hand; ih != NULL; ih = ih->ih_next) { newmask[ih->ih_ipl] |= PIC_VIRQ_TO_MASK(irq); } } /* * IPL_NONE is used for hardware interrupts that are never blocked, * and do not block anything else. */ newmask[IPL_NONE] = 0; /* * strict hierarchy - all IPLs block everything blocked by any lower * IPL */ for (u_int ipl = 1; ipl < NIPL; ipl++) { newmask[ipl] |= newmask[ipl - 1]; } #ifdef PIC_DEBUG for (u_int ipl = 0; ipl < NIPL; ipl++) { printf("%u: %08x -> %08x\n", ipl, imask[ipl], newmask[ipl]); } #endif /* * Disable all interrupts. */ for (u_int base = 0; base < num_pics; base++) { struct pic_ops * const pic = pics[base]; for (u_int i = 0; i < pic->pic_numintrs; i++) { pic->pic_disable_irq(pic, i); } } /* * Now that all interrupts are disabled, update the ipl masks. */ for (u_int ipl = 0; ipl < NIPL; ipl++) { imask[ipl] = newmask[ipl]; } /* * Lastly, enable IRQs actually in use. */ for (irq = 0, is = intrsources; irq < NVIRQ; irq++, is++) { if (is->is_hand) pic_enable_irq(is->is_hwirq); } }
// ===================================================================================================================== void irq_arch_enable(int irq) { pic_enable_irq(irq); }