00001
00002
00003
00004
00005
00006
00007
00008 #ifndef __pc_ic_h
00009 #define __pc_ic_h
00010
00011 #include <ic.h>
00012
00013 __BEGIN_SYS
00014
00015 class PC_IC: public IC_Common
00016 {
00017 private:
00018 typedef Traits<PC_IC> Traits;
00019 static const Type_Id TYPE = Type<PC_IC>::TYPE;
00020
00021 static const unsigned char INT_BASE = __SYS(Traits)<PC>::INT_BASE;
00022
00023
00024 enum {
00025 MASTER_CMD = 0x20,
00026 MASTER_IMR = 0x21,
00027 SLAVE_CMD = 0xa0,
00028 SLAVE_IMR = 0xa1
00029 };
00030
00031
00032 enum {
00033 SELECT_IRR = 0x0a,
00034 SELECT_ISR = 0x0b,
00035 ICW1 = 0x11,
00036 ICW4 = 0x01,
00037 EOI = 0x20
00038 };
00039
00040 public:
00041
00042 enum {
00043 IRQ0 = 0x1,
00044 IRQ1 = 0x2,
00045 IRQ2 = 0x4,
00046 IRQ3 = 0x8,
00047 IRQ4 = 0x10,
00048 IRQ5 = 0x20,
00049 IRQ6 = 0x40,
00050 IRQ7 = 0x80,
00051 IRQ8 = 0x100,
00052 IRQ9 = 0x200,
00053 IRQ10 = 0x400,
00054 IRQ11 = 0x800,
00055 IRQ12 = 0x1000,
00056 IRQ13 = 0x2000,
00057 IRQ14 = 0x4000,
00058 IRQ15 = 0x8000,
00059 IRQ_TIMER = IRQ0,
00060 IRQ_KEYBOARD = IRQ1
00061 };
00062
00063 public:
00064 PC_IC() {}
00065 ~PC_IC() {}
00066
00067 static void remap(unsigned char base = INT_BASE) {
00068
00069 IA32::out8(MASTER_CMD, ICW1);
00070 IA32::out8(MASTER_IMR, base);
00071 IA32::out8(MASTER_IMR, 0x04);
00072 IA32::out8(MASTER_IMR, ICW4);
00073
00074
00075 IA32::out8(SLAVE_CMD, ICW1);
00076 IA32::out8(SLAVE_IMR, base + 8);
00077 IA32::out8(SLAVE_IMR, 0x02);
00078 IA32::out8(SLAVE_IMR, ICW4);
00079 }
00080 static void enable(const Mask & mask = ALL) {
00081 IA32::out8(MASTER_IMR, IA32::in8(MASTER_IMR) & ~(unsigned char)mask);
00082 IA32::out8(SLAVE_IMR, IA32::in8(SLAVE_IMR)
00083 & ~(unsigned char)(mask >> 8));
00084 }
00085 static void disable(const Mask & mask = ALL) {
00086 IA32 cpu;
00087 IA32::out8(MASTER_IMR, IA32::in8(MASTER_IMR) | (unsigned char)mask);
00088 IA32::out8(SLAVE_IMR, IA32::in8(SLAVE_IMR)
00089 | (unsigned char)(mask >> 8));
00090 }
00091 static Mask pending() {
00092 IA32::out8(MASTER_CMD, SELECT_IRR);
00093 IA32::out8(SLAVE_CMD, SELECT_IRR);
00094 return IA32::in8(MASTER_CMD) | (IA32::in8(SLAVE_CMD) << 8);
00095 }
00096 static Mask servicing() {
00097 IA32::out8(MASTER_CMD, SELECT_ISR);
00098 IA32::out8(SLAVE_CMD, SELECT_ISR);
00099 return IA32::in8(MASTER_CMD) | (IA32::in8(SLAVE_CMD) << 8);
00100 }
00101 static Mask disabled() {
00102 return IA32::in8(MASTER_IMR) | (IA32::in8(SLAVE_IMR) << 8);
00103 }
00104 static Mask enabled() {
00105 return ~disabled();
00106 }
00107 static void eoi() {
00108 IA32::out8(MASTER_CMD, EOI);
00109 if((servicing() & 0x0004) != 0)
00110 IA32::out8(SLAVE_CMD, EOI);
00111 }
00112
00113 static int init(System_Info *si);
00114 };
00115
00116 __END_SYS
00117
00118 #endif