metalsvm/arch/x86/kernel/idt.c
Stefan Lankes 227cc19890 add alpha version of x64 support
New features:
- support of kernel tasks in 64bit mode
- support of LwIP in 64bit mode

Missing features in 64bit mode
- user-level support
- APIC support => SMP support

To create a 64bit version of the MetalSVM kernel, the compiler flags “-m64 -mno-red-zone” and the assembler flags “-felf64” has to be used. Please use qemu-system-x86_64 as test platform.

Notice, metalsvm.elf is a 32bit ELF file. However, it contains (beside the startup code) only 64bit code. This is required because GRUB doesn’t boot 64bit ELF kernels. Therefore, for disassembling via objdump the flag  “-M x86-64” has to be used.
2012-06-10 08:05:24 +02:00

88 lines
2.6 KiB
C

/*
* 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.
*/
/**
* @author Stefan Lankes
* @file arch/x86/kernel/idt.c
* @brief Definitions and functions related to IDT
*
*
* This file defines the interface for interrupts as like
* structures to describe interrupt descriptor table entries.\n
* See idt.h for flag definitions.
*/
#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
*/
static idt_entry_t idt[256] = {[0 ... 255] = {0, 0, 0, 0, 0}};
static idt_ptr_t idtp;
/*
* 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)
{
/* The interrupt routine's base address */
idt[num].base_lo = (base & 0xFFFF);
idt[num].base_hi = (base >> 16) & 0xFFFF;
#ifdef CONFIG_X86_64
idt[num].base_hi64 = (base >> 32) & 0xFFFFFFFF;
idt[num].reserved = 0x0;
#endif
/* The segment or 'selector' that this IDT entry will use
* is set here, along with any access flags */
idt[num].sel = sel;
idt[num].always0 = 0x0;
idt[num].flags = flags;
}
extern void isrsyscall(void);
/* Installs the IDT */
void idt_install(void)
{
static int initialized = 0;
if (!initialized) {
initialized = 1;
/* Sets the special IDT pointer up, just like in 'gdt.c' */
idtp.limit = (sizeof(idt_entry_t) * 256) - 1;
idtp.base = (size_t)&idt;
/* Add any new ISRs to the IDT here using idt_set_gate */
idt_set_gate(INT_SYSCALL, (size_t)isrsyscall, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING3|IDT_FLAG_32BIT|IDT_FLAG_TRAPGATE);
}
/* Points the processor's internal register to the new IDT */
asm volatile("lidt %0" : : "m" (idtp));
}