00001
00002
00003
00004
00005
00006
00007
00008 #include "../../kernel.h"
00009 #include "../../proc.h"
00010 #include "proto.h"
00011 #include <minix/portio.h>
00012 #include <ibm/cpu.h>
00013
00014 #define ICW1_AT 0x11
00015 #define ICW1_PC 0x13
00016 #define ICW1_PS 0x19
00017 #define ICW4_AT_SLAVE 0x01
00018 #define ICW4_AT_MASTER 0x05
00019 #define ICW4_PC_SLAVE 0x09
00020 #define ICW4_PC_MASTER 0x0D
00021 #define ICW4_AT_AEOI_SLAVE 0x03
00022 #define ICW4_AT_AEOI_MASTER 0x07
00023 #define ICW4_PC_AEOI_SLAVE 0x0B
00024 #define ICW4_PC_AEOI_MASTER 0x0F
00025
00026
00027
00028
00029 PUBLIC int intr_init(int mine, int auto_eoi)
00030 {
00031
00032
00033
00034
00035
00036 if (!intr_disabled())
00037 intr_disable();
00038
00039
00040
00041
00042
00043 outb( INT_CTL, machine.ps_mca ? ICW1_PS : ICW1_AT);
00044 outb( INT_CTLMASK, mine == INTS_MINIX ? IRQ0_VECTOR : BIOS_IRQ0_VEC);
00045
00046 outb( INT_CTLMASK, (1 << CASCADE_IRQ));
00047
00048 if (auto_eoi)
00049 outb( INT_CTLMASK, ICW4_AT_AEOI_MASTER);
00050 else
00051 outb( INT_CTLMASK, ICW4_AT_MASTER);
00052 outb( INT_CTLMASK, ~(1 << CASCADE_IRQ));
00053 outb( INT2_CTL, machine.ps_mca ? ICW1_PS : ICW1_AT);
00054 outb( INT2_CTLMASK, mine == INTS_MINIX ? IRQ8_VECTOR : BIOS_IRQ8_VEC);
00055
00056 outb( INT2_CTLMASK, CASCADE_IRQ);
00057 if (auto_eoi)
00058 outb( INT2_CTLMASK, ICW4_AT_AEOI_SLAVE);
00059 else
00060 outb( INT2_CTLMASK, ICW4_AT_SLAVE);
00061 outb( INT2_CTLMASK, ~0);
00062
00063
00064
00065
00066 #if IRQ0_VECTOR != BIOS_IRQ0_VEC
00067 phys_copy(BIOS_VECTOR(0) * 4L, VECTOR(0) * 4L, 8 * 4L);
00068 #endif
00069 #if IRQ8_VECTOR != BIOS_IRQ8_VEC
00070 phys_copy(BIOS_VECTOR(8) * 4L, VECTOR(8) * 4L, 8 * 4L);
00071 #endif
00072
00073 return OK;
00074 }
00075
00076
00077
00078
00079 PUBLIC int intr_disabled(void)
00080 {
00081 if(!(read_cpu_flags() & X86_FLAG_I))
00082 return 1;
00083 return 0;
00084 }
00085
00086 PUBLIC void irq_8259_unmask(int irq)
00087 {
00088 unsigned ctl_mask = irq < 8 ? INT_CTLMASK : INT2_CTLMASK;
00089 outb(ctl_mask, inb(ctl_mask) & ~(1 << (irq & 0x7)));
00090 }
00091
00092 PUBLIC void irq_8259_mask(int irq)
00093 {
00094 unsigned ctl_mask = irq < 8 ? INT_CTLMASK : INT2_CTLMASK;
00095 outb(ctl_mask, inb(ctl_mask) | (1 << (irq & 0x7)));
00096 }
00097
00098
00099 PRIVATE void i8259_disable(void)
00100 {
00101 outb(INT2_CTLMASK, 0xFF);
00102 outb(INT_CTLMASK, 0xFF);
00103 inb(INT_CTLMASK);
00104 }
00105