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); }
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); }
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); }