2010-07-31 15:53:30 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2010 Stefan Lankes, Chair for Operating Systems,
|
|
|
|
* RWTH Aachen University
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*
|
|
|
|
* This file is part of MetalSVM.
|
|
|
|
*/
|
|
|
|
|
2011-04-03 19:41:46 +02:00
|
|
|
/**
|
|
|
|
* @author Stefan Lankes
|
|
|
|
* @file arch/x86/kernel/idt.c
|
2011-04-04 11:27:49 +02:00
|
|
|
* @brief Definitions and functions related to IDT
|
2011-04-03 19:41:46 +02:00
|
|
|
*
|
|
|
|
*
|
|
|
|
* This file defines the interface for interrupts as like
|
|
|
|
* structures to describe interrupt descriptor table entries.\n
|
|
|
|
* See idt.h for flag definitions.
|
|
|
|
*/
|
|
|
|
|
2010-07-31 15:53:30 +00:00
|
|
|
#include <metalsvm/string.h>
|
|
|
|
#include <asm/idt.h>
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Declare an IDT of 256 entries. Although we will only use the
|
|
|
|
* first 32 entries in this tutorial, the rest exists as a bit
|
|
|
|
* of a trap. If any undefined IDT entry is hit, it normally
|
|
|
|
* will cause an "Unhandled Interrupt" exception. Any descriptor
|
|
|
|
* for which the 'presence' bit is cleared (0) will generate an
|
|
|
|
* "Unhandled Interrupt" exception
|
|
|
|
*/
|
2012-06-11 16:16:35 +02:00
|
|
|
#ifdef CONFIG_X86_64
|
|
|
|
static idt_entry_t idt[256] = {[0 ... 255] = {0, 0, 0, 0, 0, 0, 0}};
|
|
|
|
#else
|
2010-09-08 12:16:39 +00:00
|
|
|
static idt_entry_t idt[256] = {[0 ... 255] = {0, 0, 0, 0, 0}};
|
2012-06-11 16:16:35 +02:00
|
|
|
#endif
|
2011-04-08 10:45:26 -07:00
|
|
|
static idt_ptr_t idtp;
|
2011-04-19 18:51:59 +02:00
|
|
|
|
2012-06-13 09:57:01 +02:00
|
|
|
void configure_idt_entry(idt_entry_t *dest_entry, size_t base,
|
|
|
|
unsigned short sel, unsigned char flags)
|
|
|
|
{
|
|
|
|
/* The interrupt routine's base address */
|
|
|
|
dest_entry->base_lo = (base & 0xFFFF);
|
|
|
|
dest_entry->base_hi = (base >> 16) & 0xFFFF;
|
|
|
|
|
|
|
|
/* The segment or 'selector' that this IDT entry will use
|
|
|
|
* is set here, along with any access flags */
|
|
|
|
dest_entry->sel = sel;
|
|
|
|
dest_entry->always0 = 0;
|
|
|
|
dest_entry->flags = flags;
|
|
|
|
}
|
|
|
|
|
2011-07-31 19:17:42 +02:00
|
|
|
/*
|
|
|
|
* Use this function to set an entry in the IDT. Alot simpler
|
|
|
|
* than twiddling with the GDT ;)
|
|
|
|
*/
|
|
|
|
void idt_set_gate(unsigned char num, size_t base, unsigned short sel,
|
|
|
|
unsigned char flags)
|
|
|
|
{
|
2012-06-13 09:57:01 +02:00
|
|
|
configure_idt_entry(&idt[num], base, sel, flags);
|
2011-07-31 19:17:42 +02:00
|
|
|
}
|
|
|
|
|
2010-08-09 11:47:51 +00:00
|
|
|
extern void isrsyscall(void);
|
|
|
|
|
2010-07-31 15:53:30 +00:00
|
|
|
/* Installs the IDT */
|
|
|
|
void idt_install(void)
|
|
|
|
{
|
2011-07-18 09:14:28 +02:00
|
|
|
static int initialized = 0;
|
2010-07-31 15:53:30 +00:00
|
|
|
|
2011-07-18 09:14:28 +02:00
|
|
|
if (!initialized) {
|
|
|
|
initialized = 1;
|
|
|
|
|
|
|
|
/* Sets the special IDT pointer up, just like in 'gdt.c' */
|
|
|
|
idtp.limit = (sizeof(idt_entry_t) * 256) - 1;
|
2012-06-10 08:05:24 +02:00
|
|
|
idtp.base = (size_t)&idt;
|
2011-07-18 09:14:28 +02:00
|
|
|
|
|
|
|
/* Add any new ISRs to the IDT here using idt_set_gate */
|
2011-07-31 19:17:42 +02:00
|
|
|
idt_set_gate(INT_SYSCALL, (size_t)isrsyscall, KERNEL_CODE_SELECTOR,
|
2011-07-18 09:14:28 +02:00
|
|
|
IDT_FLAG_PRESENT|IDT_FLAG_RING3|IDT_FLAG_32BIT|IDT_FLAG_TRAPGATE);
|
|
|
|
}
|
2010-07-31 15:53:30 +00:00
|
|
|
|
|
|
|
/* Points the processor's internal register to the new IDT */
|
2011-04-08 10:45:26 -07:00
|
|
|
asm volatile("lidt %0" : : "m" (idtp));
|
2010-07-31 15:53:30 +00:00
|
|
|
}
|