void iniz( u32 idt, u32 gdt ) { exIdt = idt; exGdt = gdt; inizVConsole(); // Configuring PIT (programmable interval timer) // PIT Channel 0 - IRQ0 - scheduler INIT_PIT( PIT_CONFIG_CH0 | PIT_MODE3 | PIT_BIN | PIT_READ_LHB ); SET_PIT( PIT_DIVIDER(20), PIT_CH0 ); // Set 24-hour mode // Set binary data format wrcmos( rdcmos(CMOS_RTC_STATUSB) | 0x4 | 0x2, CMOS_RTC_STATUSB ); // If battery is low... if( !(rdcmos(CMOS_RTC_STATUSD) & 0x80) ) vsprint("warning: cmos battery is low\n"); // Configuring PIC and interrupts setTrapGate( &onIRQ0, IRQ(0) ); setTrapGate( &onIRQ1, IRQ(1) ); SET_PIC_MASK( ~0x0300 ); // Configuring scheduler inizTask( &xtask, TSS_ENTRY(0) ); LTR( xtask.uid ); currentTask = &xtask; currentTask->next = currentTask; };
void ArchBoardSpecific::irq_handler() { uint32* pic = (uint32*)PIC_BASE; if (IRQ(0)) arch_swi_irq_handler(); if (IRQ(22)) uart0_irq_handler(); if (IRQ(26)) timer0_irq_handler(); // 6-10 and 22-28 not implemented }
Error ProcessCtlHandler(ProcessID procID, ProcessOperation action, Address addr) { Process *proc = ZERO; ProcessInfo *info = (ProcessInfo *) addr; ProcessManager *procs = Kernel::instance->getProcessManager(); DEBUG("#" << procs->current()->getID() << " " << action << " -> " << procID << " (" << addr << ")"); // TODO: Verify memory address // Does the target process exist? if(action != GetPID && action != Spawn) { if (procID == SELF) proc = procs->current(); else if (!(proc = procs->get(procID))) return API::NotFound; } // Handle request switch (action) { case Spawn: proc = procs->create(addr); return proc->getID(); case KillPID: procs->remove(proc); break; case GetPID: return procs->current()->getID(); case Schedule: procs->schedule(); break; case Resume: proc->setState(Process::Ready); break; case WatchIRQ: Kernel::instance->hookInterrupt(IRQ(addr), (InterruptHandler *)interruptNotify, (ulong)proc); Kernel::instance->enableIRQ(addr, true); break; case InfoPID: info->id = proc->getID(); info->state = proc->getState(); info->userStack = proc->getUserStack(); info->kernelStack = proc->getKernelStack(); info->pageDirectory = proc->getPageDirectory(); break; case SetStack: proc->setUserStack(addr); break; } return API::Success; }
/* This one get's called from the architecture-specific interrupt * handlers, which do fiddling like EOIs (i386). */ isf_t* __attribute__((fastcall)) interrupts_callback(uint32_t intr, isf_t* regs) { struct interrupt_reg reg = interrupt_handlers[intr]; task_t* task = scheduler_get_current(); #ifdef INTERRUPTS_DEBUG debug("state before:\n"); dump_isf(LOG_DEBUG, regs); #endif if(reg.handler) { if(reg.can_reent) { interrupts_enable(); } reg.handler(regs); } #ifdef ENABLE_PICOTCP if(intr == IRQ(0)) { net_tick(); } #endif // Run scheduler every 100th tick, or when task yields if((intr == IRQ(0) && !(timer_get_tick() % 100)) || (task && task->interrupt_yield)) { if((task && task->interrupt_yield)) { task->interrupt_yield = false; } task_t* new_task = scheduler_select(regs); if(new_task && new_task->state) { #ifdef INTERRUPTS_DEBUG debug("state after (task selection):\n"); dump_isf(LOG_DEBUG, new_task->state); #endif gdt_set_tss(new_task->kernel_stack + PAGE_SIZE); return new_task->state; } } #ifdef INTERRUPTS_DEBUG debug("state after:\n"); dump_isf(LOG_DEBUG, regs); #endif return regs; }
static int atpic_vector(struct intsrc *isrc) { struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc; struct atpic *ap = (struct atpic *)isrc->is_pic; return (IRQ(ap, ai)); }
int f () { /* Handle IRQ0 = PIT timer. */ register_interrupt_handler(IRQ(0), &h, (void*)0xdeadbeef); __asm volatile("sti"); for (;;); return 0; }
void X86Kernel::interrupt(CPUState *state, ulong param) { /* End of Interrupt to slave. */ if (IRQ(state->vector) >= 8) { outb(PIC2_CMD, PIC_EOI); } /* End of Interrupt to master. */ outb(PIC1_CMD, PIC_EOI); }
void CPU::Exec() { uint8_t opCode = GetOPCode(); _instAddrMode = _addrMode[opCode]; _operand = FetchOperand(); (this->*_opTable[opCode])(); if(_prevRunIrq) { IRQ(); } }
int ProcessCtlHandler(ProcessID procID, ProcessOperation action, Address addr) { ArchProcess *proc = ZERO; ProcessInfo *info = (ProcessInfo *) addr; /* Verify memory address. */ if (action == InfoPID) { if (!memory->access(scheduler->current(), addr, sizeof(ProcessInfo))) { return EFAULT; } } /* Does the target process exist? */ if(action != GetPID && action != Spawn && !(proc = Process::byID(procID))) { return ESRCH; } /* Handle request. */ switch (action) { case Spawn: proc = new ArchProcess(addr); return proc->getID(); case KillPID: delete proc; break; case GetPID: return scheduler->current()->getID(); case Schedule: scheduler->executeNext(); break; case Resume: proc->setState(Ready); scheduler->enqueue(proc); break; case AllowIO: proc->IOPort(addr, true); break; case WatchIRQ: kernel->hookInterrupt(IRQ(addr), (InterruptHandler *)interruptNotify, (ulong)proc); kernel->enableIRQ(addr, true); break; case InfoPID: info->id = proc->getID(); info->state = proc->getState(); info->stack = proc->getStack(); info->pageDirectory = proc->getPageDirectory(); break; case SetStack: proc->setStack(addr); break; } return 0; }
void tty_keyboard_init() { flush(); // Reset send(0xF6); // Repeat rate send(0xF3); send(0); send(0xF4); flush(); interrupts_register(IRQ(1), &intr_handler, false); }
// Initialize everything that needs to be set up. void Init(void) { // Enable the PIT clock. SIM_SCGC3 |= SIM_SCGC3_ADC1_MASK; SIM_SCGC6 |= SIM_SCGC6_PIT_MASK | SIM_SCGC6_ADC0_MASK; // Turn on PIT. PIT_MCR = 0x00; // Timer 1 PIT_LDVAL1 = mcg_clk_hz /* 60;*/>> 2; // setup timer 1 for 4Hz. PIT_TCTRL1 = PIT_TCTRL_TIE_MASK; // enable Timer 1 interrupts PIT_TCTRL1 |= PIT_TCTRL_TEN_MASK; // start Timer 1 // Enable interrupts. enable_irq(IRQ(INT_PIT1)); EnableInterrupts }
static void irq_notify(void) { Context* context = get_context(); uint8_t irq = IRQ(context->num); if (!irqThread[irq]) return; Thread* receiver = thread_get(irqThread[irq]); if (receiver->state == WAIT_RECEIVING && receiver->waitingFor == 0 && receiver->waitingIrq == irq) { irqPending[irq] = false; scheduler_unblock(receiver); } else irqPending[irq] = true; }
int RK05_Service() { int irq = 0; if (rk05.rdy_cnt) { --rk05.rdy_cnt; if (0 == rk05.rdy_cnt) { rk05.rkcs |= RKCS_RDY_BIT; irq = 1; } } if (irq && (rk05.rkcs & RKCS_IDE_BIT)) { IRQ(0220); } return 0; }
void imx233_timrot_setup(unsigned timer_nr, bool reload, unsigned count, unsigned src, unsigned prescale, bool polarity, imx233_timer_fn_t fn) { int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS); /* only enable interrupt if function is set */ bool irq = fn != NULL; timer_fns[timer_nr] = fn; /* make sure we start from stop state */ HW_TIMROT_TIMCTRLn(timer_nr) = BF_OR2(TIMROT_TIMCTRLn, SELECT(BV_TIMROT_TIMCTRLn_SELECT__NEVER_TICK), UPDATE(1)); /* write count and take effect immediately with UPDATE * manual says count-1 for reload timers */ HW_TIMROT_TIMCOUNTn(timer_nr) = reload ? count - 1 : count; /* start timer */ HW_TIMROT_TIMCTRLn(timer_nr) = BF_OR6(TIMROT_TIMCTRLn, SELECT(src), PRESCALE(prescale), POLARITY(polarity), RELOAD(reload), IRQ(irq), IRQ_EN(irq)); imx233_icoll_enable_interrupt(INT_SRC_TIMER(timer_nr), irq); restore_interrupt(oldstatus); }
// Initialize the PIT void timer_init() { // preemptability setting here also affects scheduler, so leave set to false interrupts_register(IRQ(0), &timer_callback, false); rate = PIT_RATE; // The value we send to the PIT is the value to divide it's input clock // (1193180 Hz) by, to get our required frequency. Important to note is // that the divisor must be small enough to fit into 16-bits. uint32_t divisor = 1193180 / rate; // Send the command byte. outb(0x43, 0x36); // Divisor has to be sent byte-wise, so split here into upper/lower bytes. uint8_t l = (uint8_t)(divisor & 0xFF); uint8_t h = (uint8_t)( (divisor>>8) & 0xFF ); // Send the frequency divisor. outb(0x40, l); outb(0x40, h); log(LOG_DEBUG, "pit: Timer frequency %d\n", rate); }
void ArchBoardSpecific::irq_handler() { uint32* pic = (uint32*)PIC_BASE; if (IRQ(0)) arch_swi_irq_handler(); if (IRQ(1)) uart0_irq_handler(); if (IRQ(2)) arch_uart1_irq_handler(); if (IRQ(3)) keyboard_irq_handler(); if (IRQ(4)) arch_mouse_irq_handler(); if (IRQ(5)) timer0_irq_handler(); // 6-10 and 22-28 not implemented }
IntelKernel::IntelKernel(Memory::Range kernel, Memory::Range memory) : Kernel(kernel, memory) { // Set PIT interrupt frequency to 250 hertz m_pit.setFrequency(250); IntelMap map; /* ICW1: Initialize PIC's (Edge triggered, Cascade) */ IO::outb(PIC1_CMD, 0x11); IO::outb(PIC2_CMD, 0x11); /* ICW2: Remap IRQ's to interrupts 32-47. */ IO::outb(PIC1_DATA, PIC_IRQ_BASE); IO::outb(PIC2_DATA, PIC_IRQ_BASE + 8); /* ICW3: PIC2 is connected to PIC1 via IRQ2. */ IO::outb(PIC1_DATA, 0x04); IO::outb(PIC2_DATA, 0x02); /* ICW4: 8086 mode, fully nested, not buffered, no implicit EOI. */ IO::outb(PIC1_DATA, 0x01); IO::outb(PIC2_DATA, 0x01); /* OCW1: Disable all IRQ's for now. */ IO::outb(PIC1_DATA, 0xff); IO::outb(PIC2_DATA, 0xff); /* Make sure to enable PIC2 and the PIT interrupt */ enableIRQ(2, true); enableIRQ(m_pit.getInterruptVector(), true); // Install interruptRun() callback interruptRun = ::executeInterrupt; /* Setup exception handlers. */ for (int i = 0; i < 17; i++) { hookInterrupt(i, exception, 0); } /* Setup IRQ handlers. */ for (int i = 17; i < 256; i++) { /* Trap gate. */ if (i == 0x90) hookInterrupt(0x90, trap, 0); /* Hardware Interrupt. */ else hookInterrupt(i, interrupt, 0); } /* Install PIT (i8253) IRQ handler. */ hookInterrupt(IRQ(m_pit.getInterruptVector()), clocktick, 0); // Initialize TSS Segment gdt[KERNEL_TSS].limitLow = sizeof(TSS) + (0xfff / 8); gdt[KERNEL_TSS].baseLow = ((Address) &kernelTss) & 0xffff; gdt[KERNEL_TSS].baseMid = (((Address) &kernelTss) >> 16) & 0xff; gdt[KERNEL_TSS].type = 9; gdt[KERNEL_TSS].privilege = 0; gdt[KERNEL_TSS].present = 1; gdt[KERNEL_TSS].limitHigh = 0; gdt[KERNEL_TSS].granularity = 8; gdt[KERNEL_TSS].baseHigh = (((Address) &kernelTss) >> 24) & 0xff; // Fill the Task State Segment (TSS). MemoryBlock::set(&kernelTss, 0, sizeof(TSS)); kernelTss.ss0 = KERNEL_DS_SEL; kernelTss.esp0 = 0; kernelTss.bitmap = sizeof(TSS); ltr(KERNEL_TSS_SEL); }
void glInternalFlush(u32 target) { u32 i; u32 param_base = REGS32(0x8020) & 0x007FFFFF; u32 background = (REGS32(0x808C) & 0x00FFFFF8) >> 1; u32 address = (param_base + background) & 0x007FFFFF; flushPrim(); NewStripList(); BACKGROUND((u32*)&VRAM[address]); flushPrim(); NewStripList(); glClearColor((float)REGS[0x8042] / 255.0f, (float)REGS[0x8041] / 255.0f, (float)REGS[0x8040] / 255.0f, (float)REGS[0x8043] / 255.0f); glDepthMask(GL_TRUE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (cfg.ListSorting) { qsort((void*)objList, objCount, sizeof(OBJECT), comp_func); // qsort((void*)objList,objCount,sizeof(OBJECT),listtypesort_func); // qsort((void*)objList,objCount,sizeof(OBJECT),transsort_func); // qsort((void*)objList,objCount,sizeof(OBJECT),punchsort_func); } glPushMatrix(); switch (target) { case RENDER_TARGET_FRAMEBUFFER: glViewport(0, 0, 640, 480); glTranslatef(0.0f, 0.0f, -(float)RENDER_VIEW_DISTANCE); break; case RENDER_TARGET_TEXTURE: { glViewport(0, 0, 640, (REGS16(0x806E) - REGS16(0x806c) + 1)); glScalef(1.0f, -1.0f, 1.0f); glTranslatef(0.0f, -480.0f, -(float)RENDER_VIEW_DISTANCE); break; } } // DEMUL_printf(">render scene (objCount=%d)\n",objCount); for (i = 0; i < objCount; i++) { OBJECT *obj = &objList[i]; vCount = obj->vCount; if (vCount) { polygon = obj->polygon; // DEMUL_printf(">object %3d, dist = %6f, listtype = %d, pcw = %08X, isp = %08X, tsp = %08X, tcw = %08X\n",i,obj->midZ, obj->polygon.pcw.listtype, obj->polygon.pcw.all, obj->polygon.isp.all, obj->polygon.tsp.all, obj->polygon.tcw.all); if (polygon.tsp.usealpha && cfg.AlphaZWriteDisable) polygon.isp.zwritedis = 1; SetupShadeMode(); SetupCullMode(); SetupZBuffer(); if (cfg.Wireframe) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } else { SetupAlphaTest(); SetupAlphaBlend(); SetupTexture(); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } glDrawElements(GL_TRIANGLES, vCount, GL_UNSIGNED_INT, &pIndex[obj->vIndex]); } } glPopMatrix(); // ProfileFinish(0); IRQ(0x0002); switch (target) { case RENDER_TARGET_FRAMEBUFFER: SwapBuffers(hdc); break; case RENDER_TARGET_TEXTURE: { u32 tw = REGS32(0x804C) << 2; u32 th = 512; glReadBuffer(GL_BACK); glBindTexture(GL_TEXTURE_2D, backbufname); glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, tw, th, 0); isFramebufferRendered = 1; TextureAddress = REGS32(0x8060) & 0x007FFFFF; break; } } // DEMUL_printf(">render end\n"); // DEMUL_printf(">frame summary (maxz=%f,minz=%f)\n",maxz,minz); maxz = -10000000.0f; minz = 10000000.0f; objCount = 0; vIndex = 0; vCount = 0; vVertex = 0; }
X86Kernel::X86Kernel() : Kernel(), ticks(0) { /* ICW1: Initialize PIC's (Edge triggered, Cascade) */ outb(PIC1_CMD, 0x11); outb(PIC2_CMD, 0x11); /* ICW2: Remap IRQ's to interrupts 32-47. */ outb(PIC1_DATA, PIC_IRQ_BASE); outb(PIC2_DATA, PIC_IRQ_BASE + 8); /* ICW3: PIC2 is connected to PIC1 via IRQ2. */ outb(PIC1_DATA, 0x04); outb(PIC2_DATA, 0x02); /* ICW4: 8086 mode, fully nested, not buffered, no implicit EOI. */ outb(PIC1_DATA, 0x01); outb(PIC2_DATA, 0x01); /* OCW1: Disable all IRQ's for now. */ outb(PIC1_DATA, 0xff); outb(PIC2_DATA, 0xff); /* Let the i8253 timer run continuously (square wave). */ outb(PIT_CMD, 0x36); outb(PIT_CHAN0, PIT_DIVISOR & 0xff); outb(PIT_CHAN0, PIT_DIVISOR >> 8); /* Make sure to enable PIC2 and the i8253. */ enableIRQ(2, true); enableIRQ(0, true); /* Setup exception handlers. */ for (int i = 0; i < 17; i++) { hookInterrupt(i, exception, 0); } /* Setup IRQ handlers. */ for (int i = 17; i < 256; i++) { /* Trap gate. */ if (i == 0x90) hookInterrupt(0x90, trap, 0); /* Hardware Interrupt. */ else hookInterrupt(i, interrupt, 0); } /* Install PIT (i8253) IRQ handler. */ hookInterrupt(IRQ(0), clocktick, 0); /* Initialize TSS Segment. */ gdt[USER_TSS].limitLow = sizeof(TSS) + (0xfff / 8); gdt[USER_TSS].baseLow = ((Address) &kernelTss) & 0xffff; gdt[USER_TSS].baseMid = (((Address) &kernelTss) >> 16) & 0xff; gdt[USER_TSS].type = 9; gdt[USER_TSS].privilege = 0; gdt[USER_TSS].present = 1; gdt[USER_TSS].limitHigh = 0; gdt[USER_TSS].granularity = 8; gdt[USER_TSS].baseHigh = (((Address) &kernelTss) >> 24) & 0xff; /* Let TSS point to I/O bitmap page. */ kernelTss.bitmap = PAGESIZE << 16; /* Load Task State Register. */ ltr(USER_TSS_SEL); }
void ArchBoardSpecific::irq_handler() { uint32* pic = (uint32*)PIC_BASE; if (IRQ(0)) timer0_irq_handler(); }
Error ProcessCtlHandler(ProcessID procID, ProcessOperation action, Address addr) { #ifdef __i386__ IntelProcess *proc = ZERO; Memory *memory = Kernel::instance->getMemory(); ProcessInfo *info = (ProcessInfo *) addr; ProcessManager *procs = Kernel::instance->getProcessManager(); DEBUG("#" << procs->current()->getID() << " " << action << " -> " << procID << " (" << addr << ")"); /* Verify memory address. */ if (action == InfoPID) { if (!memory->access(procs->current(), addr, sizeof(ProcessInfo))) { return API::AccessViolation; } } /* Does the target process exist? */ if(action != GetPID && action != Spawn) { if (procID == SELF) proc = (IntelProcess *) procs->current(); else if (!(proc = (IntelProcess *)procs->get(procID))) return API::NotFound; } /* Handle request. */ switch (action) { case Spawn: proc = (IntelProcess *) procs->create(addr); return proc->getID(); case KillPID: procs->remove(proc); break; case GetPID: return procs->current()->getID(); case Schedule: procs->schedule(); break; case Resume: proc->setState(Process::Ready); break; case AllowIO: return API::InvalidArgument; //proc->IOPort(addr, true); //break; case WatchIRQ: Kernel::instance->hookInterrupt(IRQ(addr), (InterruptHandler *)interruptNotify, (ulong)proc); Kernel::instance->enableIRQ(addr, true); break; case InfoPID: info->id = proc->getID(); info->state = proc->getState(); info->stack = proc->getStack(); info->pageDirectory = proc->getPageDirectory(); break; case SetStack: proc->setStack(addr); break; } #endif return API::Success; }
else parent = (control & PM_BIT(PLLSEL)) ? &pll0 : &osc0; clk->parent = parent; } static struct dw_dma_platform_data dw_dmac0_data = { .nr_channels = 3, .block_size = 4095U, .nr_masters = 2, .data_width = { 2, 2, 0, 0 }, }; static struct resource dw_dmac0_resource[] = { PBMEM(0xff200000), IRQ(2), }; DEFINE_DEV_DATA(dw_dmac, 0); DEV_CLK(hclk, dw_dmac0, hsb, 10); /* -------------------------------------------------------------------- * System peripherals * -------------------------------------------------------------------- */ static struct resource at32_pm0_resource[] = { { .start = 0xfff00000, .end = 0xfff0007f, .flags = IORESOURCE_MEM, }, IRQ(20), };
IntelKernel::IntelKernel(Memory::Range kernel, Memory::Range memory) : Kernel(kernel, memory) { Arch::Memory mem; /* ICW1: Initialize PIC's (Edge triggered, Cascade) */ IO::outb(PIC1_CMD, 0x11); IO::outb(PIC2_CMD, 0x11); /* ICW2: Remap IRQ's to interrupts 32-47. */ IO::outb(PIC1_DATA, PIC_IRQ_BASE); IO::outb(PIC2_DATA, PIC_IRQ_BASE + 8); /* ICW3: PIC2 is connected to PIC1 via IRQ2. */ IO::outb(PIC1_DATA, 0x04); IO::outb(PIC2_DATA, 0x02); /* ICW4: 8086 mode, fully nested, not buffered, no implicit EOI. */ IO::outb(PIC1_DATA, 0x01); IO::outb(PIC2_DATA, 0x01); /* OCW1: Disable all IRQ's for now. */ IO::outb(PIC1_DATA, 0xff); IO::outb(PIC2_DATA, 0xff); /* Let the i8253 timer run continuously (square wave). */ IO::outb(PIT_CMD, 0x36); IO::outb(PIT_CHAN0, PIT_DIVISOR & 0xff); IO::outb(PIT_CHAN0, PIT_DIVISOR >> 8); /* Make sure to enable PIC2 and the i8253. */ enableIRQ(2, true); enableIRQ(0, true); // Install interruptRun() callback interruptRun = ::executeInterrupt; /* Setup exception handlers. */ for (int i = 0; i < 17; i++) { hookInterrupt(i, exception, 0); } /* Setup IRQ handlers. */ for (int i = 17; i < 256; i++) { /* Trap gate. */ if (i == 0x90) hookInterrupt(0x90, trap, 0); /* Hardware Interrupt. */ else hookInterrupt(i, interrupt, 0); } /* Install PIT (i8253) IRQ handler. */ hookInterrupt(IRQ(0), clocktick, 0); // Initialize TSS Segment gdt[KERNEL_TSS].limitLow = sizeof(TSS) + (0xfff / 8); gdt[KERNEL_TSS].baseLow = ((Address) &kernelTss) & 0xffff; gdt[KERNEL_TSS].baseMid = (((Address) &kernelTss) >> 16) & 0xff; gdt[KERNEL_TSS].type = 9; gdt[KERNEL_TSS].privilege = 0; gdt[KERNEL_TSS].present = 1; gdt[KERNEL_TSS].limitHigh = 0; gdt[KERNEL_TSS].granularity = 8; gdt[KERNEL_TSS].baseHigh = (((Address) &kernelTss) >> 24) & 0xff; // Fill the Task State Segment (TSS). MemoryBlock::set(&kernelTss, 0, sizeof(TSS)); kernelTss.esp0 = mem.range(Memory::KernelStack).virt + mem.range(Memory::KernelStack).size; kernelTss.ss0 = KERNEL_DS_SEL; kernelTss.bitmap = sizeof(TSS); // Load Task State Register ltr(KERNEL_TSS_SEL); }