irq.c (4081B)
1 #include <module.h> 2 #include <types.h> 3 #include <pc/idt/idt.h> 4 #include <pc/io/io.h> 5 #include <pc/irq/irq.h> 6 #include <interfaceUtilisateur/console/console.h> /* DEBUG */ 7 8 MODULE(Irq); 9 10 DEPENDANCE_MODULE(Irq, Idt); 11 DEPENDANCE_MODULE(Irq, Io); 12 13 extern GestionnaireRequeteInterruption tableFonctionsEnvoiFinInterruption[]; 14 extern GestionnaireRequeteInterruption tableGestionnairesRequeteInterruption[]; 15 16 void gestionnaireRequeteInterruptionVide() { 17 } 18 19 void initIrq (void** etat) { 20 desactiverInterruptions(); 21 22 *etat = etatIrq; 23 24 etatIrq->tableFonctionsEnvoiFinInterruption = tableFonctionsEnvoiFinInterruption; 25 etatIrq->tableGestionnairesRequeteInterruption = tableGestionnairesRequeteInterruption; 26 27 etatIrq->adresseVecteurInterruptionMaitre = 32; 28 etatIrq->adresseVecteurInterruptionEsclave = 32 + 8; 29 30 etatIrq->masqueMaitre = 0xff & (~(1 << 2)); /* connexion avec l'esclave activée */ 31 etatIrq->masqueEsclave = 0xff; 32 33 etatIrq->ancienMasqueMaitre = inb(PORT_PIC_MAITRE_DONNEES); 34 etatIrq->ancienMasqueEsclave = inb(PORT_PIC_ESCLAVE_DONNEES); 35 36 37 etatIrq->ICW1_Maitre = (PicICW1){ 38 .ICW4_present = TRUE, 39 .single = PIC_ICW1_CASCADE, 40 .adi = PIC_ICW1_INTERVALLE_8, 41 .ltim = PIC_ICW1_EDGE_TRIGGERED_MODE, 42 .init = 1, 43 ._zero = 0 44 }; 45 46 etatIrq->ICW2_Maitre = (PicICW2){ 47 ._zero = 0, 48 .adresseVecteurInterruption_7_3 = etatIrq->adresseVecteurInterruptionMaitre >> 3 49 }; 50 51 etatIrq->ICW3_Maitre = ESCLAVE_CONNECTE_SUR_MAITRE_PATTE(2); 52 53 etatIrq->ICW4_Maitre = (PicICW4){ 54 .microPM = PIC_ICW4_MODE_8086_8088, 55 .autoEOI = FALSE, 56 .tampon = PIC_ICW4_MODE_SANS_TAMPON, 57 .specialFullyNestedMode = FALSE 58 }; 59 60 61 etatIrq->ICW1_Esclave = etatIrq->ICW1_Maitre; 62 63 etatIrq->ICW2_Esclave = (PicICW2){ 64 ._zero = 0, 65 .adresseVecteurInterruption_7_3 = etatIrq->adresseVecteurInterruptionEsclave >> 3 66 }; 67 68 etatIrq->ICW3_Esclave = (PicICW3_Esclave){ 69 .patteConnexionMaitre = 2, 70 ._zero = 0 71 }; 72 73 etatIrq->ICW4_Esclave = etatIrq->ICW4_Maitre; 74 75 76 outb (PORT_PIC_MAITRE_COMMANDE, etatIrq->ICW1_Maitre); 77 outb (PORT_PIC_MAITRE_DONNEES, etatIrq->ICW2_Maitre); 78 outb (PORT_PIC_MAITRE_DONNEES, etatIrq->ICW3_Maitre); 79 outb (PORT_PIC_MAITRE_DONNEES, etatIrq->ICW4_Maitre); 80 outb (PORT_PIC_MAITRE_DONNEES, etatIrq->masqueMaitre); 81 82 outb (PORT_PIC_ESCLAVE_COMMANDE, etatIrq->ICW1_Esclave); 83 outb (PORT_PIC_ESCLAVE_DONNEES, etatIrq->ICW2_Esclave); 84 outb (PORT_PIC_ESCLAVE_DONNEES, etatIrq->ICW3_Esclave); 85 outb (PORT_PIC_ESCLAVE_DONNEES, etatIrq->ICW4_Esclave); 86 outb (PORT_PIC_ESCLAVE_DONNEES, etatIrq->masqueEsclave); 87 88 int i; 89 for (i = 0; i < 8; i++) { 90 definirGestionnaireInterruption(etatIrq->adresseVecteurInterruptionMaitre + i, tableFonctionsEnvoiFinInterruption[i]); 91 } 92 93 for (i = 0; i < 8; i++) 94 definirGestionnaireInterruption(etatIrq->adresseVecteurInterruptionEsclave + i, tableFonctionsEnvoiFinInterruption[i+8]); 95 activerInterruptions(); 96 } 97 98 void deinitIrq (void** etat) { 99 *etat = NULL; 100 } 101 102 void definirGestionnaireRequeteInterruption(int ligne, GestionnaireRequeteInterruption gestionnaire) { 103 desactiverInterruptions(); 104 105 etatIrq->tableGestionnairesRequeteInterruption[ligne] = gestionnaire; 106 107 activerInterruptions(); 108 } 109 110 void activerLigneRequeteInterruption(int ligne) { 111 if (ligne < 8) { 112 activerInterruption(etatIrq->adresseVecteurInterruptionMaitre + ligne); 113 etatIrq->masqueMaitre &= ~(1 << (ligne & 0x07)); 114 outb (PORT_PIC_MAITRE_DONNEES, etatIrq->masqueMaitre); 115 } else { 116 activerInterruption(etatIrq->adresseVecteurInterruptionEsclave + ligne - 8); 117 etatIrq->masqueEsclave &= ~(1 << (ligne & 0x07)); 118 outb (PORT_PIC_ESCLAVE_DONNEES, etatIrq->masqueEsclave); 119 } 120 } 121 122 void desactiverLigneRequeteInterruption(int ligne) { 123 if (ligne < 8) { 124 desactiverInterruption(etatIrq->adresseVecteurInterruptionMaitre + ligne); 125 etatIrq->masqueMaitre |= (1 << (ligne & 0x07)); 126 outb (PORT_PIC_MAITRE_DONNEES, etatIrq->masqueMaitre); 127 } else { 128 desactiverInterruption(etatIrq->adresseVecteurInterruptionEsclave + ligne - 8); 129 etatIrq->masqueEsclave |= (1 << (ligne & 0x07)); 130 outb (PORT_PIC_ESCLAVE_DONNEES, etatIrq->masqueEsclave); 131 } 132 }