/* * (C) Copyright 2002 * Daniel Engstr�m, Omicron Ceti AB, daniel@omicron.se. * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #include <common.h> #include <asm/interrupt.h> struct idt_entry { u16 base_low; u16 selector; u8 res; u8 access; u16 base_high; } __attribute__ ((packed)); struct idt_entry idt[256]; asm (".globl irq_return\n" "irq_return:\n" " addl $4, %esp\n" " popa\n" " iret\n"); void __attribute__ ((regparm(0))) default_isr(void); asm ("default_isr: iret\n"); asm ("idt_ptr:\n" ".word 0x800\n" /* size of the table 8*256 bytes */ ".long idt\n" /* offset */ ".word 0x18\n");/* data segment */ void set_vector(u8 intnum, void *routine) { idt[intnum].base_high = (u16)((u32)(routine + gd->reloc_off) >> 16); idt[intnum].base_low = (u16)((u32)(routine + gd->reloc_off) & 0xffff); } int cpu_init_interrupts(void) { int i; /* Just in case... */ disable_interrupts(); /* Setup the IDT */ for (i=0;i<256;i++) { idt[i].access = 0x8e; idt[i].res = 0; idt[i].selector = 0x10; set_vector(i, default_isr); } asm ("cs lidt idt_ptr\n"); /* It is now safe to enable interrupts */ enable_interrupts(); return 0; } void enable_interrupts(void) { asm("sti\n"); } int disable_interrupts(void) { long flags; asm volatile ("pushfl ; popl %0 ; cli\n" : "=g" (flags) : ); return (flags&0x200); /* IE flags is bit 9 */ }