My Project
Chargement...
Recherche...
Aucune correspondance
intel-8259a.c
Aller à la documentation de ce fichier.
1/*----------------------------------------------------------------------------*/
2/* Implémentation des sous-programmes de gestion du PIC intel 8259A. */
3/* */
4/* On suppose ici une architecture de type PC-AT, avec deux PICs en cascade */
5/* */
6/* Voir https://wiki.osdev.org/PIC */
7/* */
8/* (C) Manu Chaput 2000-2021 */
9/*----------------------------------------------------------------------------*/
10#include <manux/config.h>
11
12#include <manux/memoire.h> // NULL
13#include <manux/io.h>
14#include <manux/types.h>
15#include <manux/errno.h>
16
17#include <manux/intel-8259a.h>
18
22typedef struct {
23 void (* handler)(void *);
24 void * private;;
26
31
36
37/*
38 * Quelques macros utiles
39 */
40#define PIC_EOI 0x20 // Confirmation d'une interruption
41
42// Premier mot de configuration
43#define ICW1_INIT 0x10 // Initialisation
44#define ICW1_ICW4 0x01 // Config en 4 mots
45
46// Troisième mot de configuration
47#define ICW3_ESCLAVE2 0x02 // Pour un esclave sur IRQ2
48#define ICW3_MAITRE2 0x04 // Pour un maître avec une cascade sur IRQ2
49
50// Quatrième mot de configuration
51#define ICW4_8086 0x01 // Config de base (x86)
52
53// WARNING pas l'idéal !
54#define delaiOutB {for(int __x = 0; __x<20; __x++){asm("");}}
55/*
56 * Initialisation des PICs.
57 *
58 * intBase stipule le numéro d'interruption correspondant à l'IRQ 0 du maître.
59 * pour l'esclave, c'est en suivant (donc intBase + 8).
60 */
61void i8259aInit(uint8_t intBase)
62{
63 uint8_t m, s;
64 int i;
65
66 // On sauve les masques
69
70 // On envoie les 4 mots d'initialisation au maître
71
72 // Premier mot ICW1 : initialisation (ICW1_INIT) en 4 mots (ICW1_ICW4)
75
76 // Deuxième mot : la base des INT
79
80 // Troisième mot : le second est en cascade sur IRQ 2
83
84 // Quatrième mot : config de base
86
87 // Premier mot ICW1 : initialisation (ICW1_INIT) en 4 mots (ICW1_ICW4)
90
91 // Deuxième mot : la base des INT
92 outb(PIC_ESCLAVE_PORT_DONNEE, intBase + 8);
94
95 // Troisième mot :il est en cascade du maître
98
99 // Quatrième mot : config de base
101 delaiOutB;
102
103 // On restaure les masques
104 outb(PIC_MAITRE_PORT_DONNEE, m);//|0xff);
105 outb(PIC_ESCLAVE_PORT_DONNEE, s);//|0xff);
106
107 // On met à NULL les handlers
108 for (i = 0; i < I8259A_NB_IRQ; i++) {
109 nbHandlerClients[i] = 0;
110 // handlerClients[i].handler = (void (*)(void *)) NULL;
111 // handlerClients[i].private = NULL;
112 }
113}
114
118int i8259aAjouterHandler(int numIRQ, void (*handler)(void *), void * private)
119{
120 // On ne gère que un handler par IRQ
122 return ENOMEM;
123 }
124
125 handlerClients[numIRQ][nbHandlerClients[numIRQ]].handler = handler;
126 handlerClients[numIRQ][nbHandlerClients[numIRQ]].private = private;
127
128 nbHandlerClients[numIRQ] ++;
129
130 return ESUCCES;
131}
132
137{
138 char masque;
140
141 // Circuit esclave (0x0f > numIRQ >= 0x08) ?
142 if (numIRQ & 0x08) {
144 numIRQ &= 0x07; // On ne garde que les 3 derniers bits
145 }
146
147 // On lit le masque actuel
148 inb(port, masque);
149
150 // On positionne le masque modifié
151 outb(port, masque & (0x01 << numIRQ));
152}
153
158{
159 char masque;
161
162 // Circuit esclave (0x0f > numIRQ >= 0x08) ?
163 if (numIRQ & 0x08) {
165 numIRQ &= 0x07; // On ne garde que les 3 derniers bits
166 }
167
168 // On lit le masque actuel
169 inb(port, masque);
170
171 // On positionne le masque modifié
172 outb(port, masque & ~(0x01 << numIRQ));
173}
174
182{
183 // Si c'est suite à une interruption de l'esclave il faut *aussi*
184 // prévenir le maître (cascade)
185 if (numIRQ & 0x08) {
187 }
189}
190
196void i8259aGestionIRQ(TousRegistres registres, uint32_t numIRQ,
197 uint32_t eip, uint32_t cs, uint32_t eFlags)
198{
199 int i;
200
201 (void) registres;
202 (void) eip;
203 (void) cs;
204 (void) eFlags;
205
206 // On accuse réception auprès du PIC
207 i8259aAckIRQ(numIRQ);
208
209 // On invoque les handlers de tous les clients
210 for (i = 0 ; i < nbHandlerClients[numIRQ]; i++) {
211 if (handlerClients[numIRQ][i].handler) {
212 handlerClients[numIRQ][i].handler(handlerClients[numIRQ][i].private);
213 }
214 }
215}
#define I8259A_NB_IRQ
Definition intel-8259a.h:16
#define MANUX_NB_HANDLER_PAR_IRQ
Definition intel-8259a.h:10
#define ENOMEM
Definition errno.h:13
#define ESUCCES
Definition errno.h:10
typedef void(Handler(void))
unsigned long uint32_t
Definition types.h:20
unsigned short uint16_t
Definition types.h:16
unsigned char uint8_t
Definition types.h:12
void i8259aInterdireIRQ(uint8_t numIRQ)
#define PIC_EOI
Definition intel-8259a.c:40
#define ICW1_INIT
Definition intel-8259a.c:43
#define ICW3_MAITRE2
Definition intel-8259a.c:48
#define ICW4_8086
Definition intel-8259a.c:51
void i8259aGestionIRQ(TousRegistres registres, uint32_t numIRQ, uint32_t eip, uint32_t cs, uint32_t eFlags)
Le handler de gestion effective des IRQ.
int i8259aAjouterHandler(int numIRQ, void(*handler)(void *), void *private)
Ajout d'un handler.
#define ICW1_ICW4
Definition intel-8259a.c:44
#define ICW3_ESCLAVE2
Definition intel-8259a.c:47
void i8259aAutoriserIRQ(uint8_t numIRQ)
Masquage d'une IRQ.
void i8259aInit(uint8_t intBase)
Definition intel-8259a.c:61
i8259aClient handlerClients[I8259A_NB_IRQ][MANUX_NB_HANDLER_PAR_IRQ]
Definition intel-8259a.c:30
int nbHandlerClients[I8259A_NB_IRQ]
Definition intel-8259a.c:35
void i8259aAckIRQ(uint8_t numIRQ)
Accusé de réception d'une IRQ.
#define delaiOutB
Definition intel-8259a.c:54
#define outb(port, octet)
Emission d'un octet sur un port.
Definition io.h:13
#define inb(port, adresseOctet)
Lecture d'un octet depuis un port.
Definition io.h:19
#define PIC_ESCLAVE_PORT_COMMANDE
Definition intel-8259a.h:15
#define PIC_MAITRE_PORT_DONNEE
Definition intel-8259a.h:14
#define PIC_ESCLAVE_PORT_DONNEE
Definition intel-8259a.h:16
#define PIC_MAITRE_PORT_COMMANDE
Definition intel-8259a.h:13
Structure permettant de définir un matériel "client".
Definition intel-8259a.c:22
void(* handler)(void *)
Definition intel-8259a.c:23
void * private
Definition intel-8259a.c:24