interrupts.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*
  2. * (C) Copyright 2002
  3. * Daniel Engström, Omicron Ceti AB, daniel@omicron.se.
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. #include <common.h>
  24. #include <asm/interrupt.h>
  25. struct idt_entry {
  26. u16 base_low;
  27. u16 selector;
  28. u8 res;
  29. u8 access;
  30. u16 base_high;
  31. } __attribute__ ((packed));
  32. struct idt_entry idt[256];
  33. asm (".globl irq_return\n"
  34. "irq_return:\n"
  35. " addl $4, %esp\n"
  36. " popa\n"
  37. " iret\n");
  38. void __attribute__ ((regparm(0))) default_isr(void);
  39. asm ("default_isr: iret\n");
  40. asm ("idt_ptr:\n"
  41. ".word 0x800\n" /* size of the table 8*256 bytes */
  42. ".long idt\n" /* offset */
  43. ".word 0x18\n");/* data segment */
  44. void set_vector(u8 intnum, void *routine)
  45. {
  46. idt[intnum].base_high = (u16)((u32)(routine)>>16);
  47. idt[intnum].base_low = (u16)((u32)(routine)&0xffff);
  48. }
  49. int cpu_init_interrupts(void)
  50. {
  51. int i;
  52. /* Just in case... */
  53. disable_interrupts();
  54. /* Setup the IDT */
  55. for (i=0;i<256;i++) {
  56. idt[i].access = 0x8e;
  57. idt[i].res = 0;
  58. idt[i].selector = 0x10;
  59. set_vector(i, default_isr);
  60. }
  61. asm ("cs lidt idt_ptr\n");
  62. /* It is now safe to enable interrupts */
  63. enable_interrupts();
  64. return 0;
  65. }
  66. void enable_interrupts(void)
  67. {
  68. asm("sti\n");
  69. }
  70. int disable_interrupts(void)
  71. {
  72. long flags;
  73. asm volatile ("pushfl ; popl %0 ; cli\n" : "=g" (flags) : );
  74. return (flags&0x200); /* IE flags is bit 9 */
  75. }