Beispiel #1
0
void gdt_install(void)
{
	gdt_ptr.limit = sizeof(gdt) - 1;
	gdt_ptr.base = (unsigned int)&gdt;

	memset(gdt, 0, sizeof(gdt));

	// Kernel space
	gdt_set_gate(&gdt[GDT_KERNEL_CS].memseg, 0, 0xFFFFF, 0, 1);
	gdt_set_gate(&gdt[GDT_KERNEL_DS].memseg, 0, 0xFFFFF, 0, 0);

	// User space
	gdt_set_gate(&gdt[GDT_USER_CS].memseg, 0, 0xFFFFF, 3, 1);
	gdt_set_gate(&gdt[GDT_USER_DS].memseg, 0, 0xFFFFF, 3, 0);

	// IRQ, faults, thread
	gdt_set_tss(&gdt[GDT_HW_INT_TSS].tss, &kernel_tasks.tss_for_hw_int);
	gdt_set_tss(&gdt[GDT_PAGE_FAULT_TSS].tss, &kernel_tasks.tss_for_page_fault);
	gdt_set_tss(&gdt[GDT_DOUBLE_FAULT_TSS].tss, &kernel_tasks.tss_for_double_fault);
	gdt_set_tss(&gdt[GDT_ACTIVE_THREAD_TSS].tss, &kernel_tasks.tss_for_active_thread);

	asm_gdt_flush(&gdt_ptr);
	asm_set_tr(8 * GDT_ACTIVE_THREAD_TSS);
}
Beispiel #2
0
/* 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;
}
Beispiel #3
0
void gdt_init()
{
	memset(&gdt_entries, 0, sizeof(gdt_entries));

    gdt_set_gate(0, 0, 0, 0, 0);            // 0x0  Null segment
    gdt_set_gate(1, 0, 0xFFFF, 0x98, 0x20); 		// 0x8  Kernel Code segment
    gdt_set_gate(2, 0, 0xFFFF, 0x90, 0x00); 		// 0x10 Kernel Data segment
    gdt_set_gate(3, 0, 0xFFFF, 0xF8, 0x20); 		// 0x18 User mode code segment
    gdt_set_gate(4, 0, 0xFFFF, 0xF0, 0x00); 		// 0x20 User mode data segment

    gdt_set_tss();						 	        // 0x28 TSS64

    gdt_ptr.limit = sizeof(gdt_entries) - 1;
    gdt_ptr.base  = (u64)&gdt_entries;

    gdt_flush(&gdt_ptr);

    tss_flush();
}