My Project
Chargement...
Recherche...
Aucune correspondance
pci.c
Aller à la documentation de ce fichier.
1
10#include <manux/pci.h>
11#include <manux/io.h> // inl/outl/...
12#include <manux/memoire.h> // NULL
13#include <manux/debug.h>
14
18#define PCI_NB_EQUIP_PAR_BUS 8 //32
19
23#ifndef PCI_CONFIG_ADDRESS
24# define PCI_CONFIG_ADDRESS 0xCF8
25#endif
26#ifndef PCI_CONFIG_DATA
27# define PCI_CONFIG_DATA 0xCFC
28#endif
29
33#define MANUX_NB_BUS_PCI 1
34
38#define PCI_ID_VENDEUR 0x00
39#define PCI_ID_EQUIPEMENT 0x02
40#define PCI_REVISION 0x08
41#define PCI_INTERRUPTION 0x3C
42#define PCI_BAR_0 0x10 // Base Address Register
43#define PCI_BAR_1 0x14
44#define PCI_BAR_2 0x18
45#define PCI_BAR_3 0x1C
46#define PCI_BAR_4 0x20
47#define PCI_BAR_5 0x24
48
52#define PCI_BAR_IO 0x01
53#define PCI_AUCUN_VENDEUR 0xFFFF
54
59int PCINombreEquipements = 0; // Le nombre d'équipements détectés
60
62
75uint32_t PCILireLong(uint8_t bus, uint8_t slot, uint8_t fonction, uint8_t offset)
76{
77 uint32_t result;
78 uint32_t adresse = (((uint32_t)bus) << 16)
79 | (((uint32_t)slot) << 11)
80 | (((uint32_t)fonction) << 8)
81 | (((uint32_t)offset) & 0xFC)
82 | ((uint32_t)0x80000000);
83
84 // On envoie l'adresse qui nous intéresse
86
87 // On y lit un long conformément à [1]
89
90 return result;
91}
92
93uint16_t PCILireMot(uint8_t bus, uint8_t slot, uint8_t fonction, uint8_t offset)
94{
95 uint16_t result;
96
97 // Si l'offset nous fait pointer sur le mot de poids fort, on décale
98 // à gauche d'un mot (2 * 8). Sinon non (0 * 8). Puis on masque car
99 // on ne veut qu'un mot
100 result = (uint16_t)(PCILireLong(bus, slot, fonction,
101 offset & ((uint16_t)~0x3)) >> ((offset & 2) * 8))& 0xFFFF;
102
103 return result;
104}
105
106uint8_t PCILireOctet(uint8_t bus, uint8_t slot, uint8_t fonction, uint8_t offset)
107{
108 uint8_t result;
109
110 // On décale de 0 à 3 octets en fonction des 3 bits de poids faible
111 result = (uint8_t)(PCILireLong(bus, slot, fonction, offset & ~0x3) >> ((offset & 3) * 8))& 0xFF;
112
113 return result;
114}
115
121static
122void PCIEnumerationDesEquipementsDuBus(uint8_t bus)
123{
124 uint8_t numEquipement; // Pour boucler
125 uint16_t idVendeur;
126 uint16_t idEquipement;
127 uint32_t adresse; // Pour chercher les adresse d'E/S
128 uint8_t bar; // Parcourir les BAR
129
130 for (numEquipement = 0; numEquipement < PCI_NB_EQUIP_PAR_BUS; numEquipement++) {
131 //printk(PRINTK_CRITIQUE"id/nb %3d/%3d\r", numEquipement, PCI_NB_EQUIP_PAR_BUS);
132
133 // Lecture des numéros de vendeur et d'équipement
134 idVendeur = PCILireMot(bus, numEquipement, 0, PCI_ID_VENDEUR);
135
136 if (idVendeur != PCI_AUCUN_VENDEUR) {
138 printk(PRINTK_CRITIQUE"Trop d'equipements PCI pour moi (%d vs %d)!\n",
140 return;
141 }
142 idEquipement = PCILireMot(bus, numEquipement, 0, PCI_ID_EQUIPEMENT);
143
144 // Les identifiants
147
153
154
155 // L'interruption
157 PCILireOctet(bus, numEquipement, 0, PCI_INTERRUPTION);
158
159 // On cherche l'adresse d'E/S
160 // On parcourt tous les registres mémoire
161 for (bar = PCI_BAR_0; bar <= PCI_BAR_5; bar += 4) {
162 adresse = PCILireLong(0, numEquipement, 0, bar);
163 // Est-ce une adresse d'E/S ?
164 if (adresse & PCI_BAR_IO) {
165 // On est aligné sur 32 bits, les 2 bits de poids faible sont donc
166 // non signifiants
168 } else {
169 printk_debug(DBG_KERNEL_A_FAIRE, "Memory BARs a prendre en compte !\n");
170 }
171 }
172
173 printk_debug(DBG_KERNEL_PCI, "[%d] Vd/Id 0x%x/0x%x\n",
174 PCINombreEquipements, idVendeur, idEquipement);
176 }
177 }
178}
179
181{
182 uint8_t bus;
183
184 printk_debug(DBG_KERNEL_PCI, "Enum. des equip. PCI ...\n");
185
186 for (bus = 0; bus < MANUX_NB_BUS_PCI; bus++) {
187 printk(PRINTK_CRITIQUE" - bus %3d/%3d\r", bus, MANUX_NB_BUS_PCI);
188 PCIEnumerationDesEquipementsDuBus(bus);
189 }
191
192 printk_debug(DBG_KERNEL_PCI, "%d equipements PCI\n", PCINombreEquipements);
193}
194
206int PCIObtenirProchainEquipement(uint16_t vendeur, uint16_t equipement, int precedent)
207{
208 int result = precedent;
209
210 while ((++result < PCINombreEquipements)
211 && ((PCIEquipements[result].vendeur != vendeur)
212 || (PCIEquipements[result].equipement != equipement))
213 ) {}
214
215 if (result >= PCINombreEquipements)
216 result = -1;
217
218 return result;
219}
220
227{
228 if ((n >= 0) && (n < PCINombreEquipements))
229 return &(PCIEquipements[n]);
230
231 return NULL;
232}
#define MANUX_NB_MAX_EQUIPEMENTS_PCI
Definition pci.h:12
#define PRINTK_CRITIQUE
Definition printk.h:28
void printk(char *format,...)
Fonction principale d'affichage dans le noyau.
Definition printk.c:166
#define NULL
Definition stddef.h:10
unsigned long uint32_t
Definition types.h:20
unsigned short uint16_t
Definition types.h:16
unsigned char uint8_t
Definition types.h:12
#define inl(port, adresseLong)
Lecture d'un long depuis un port.
Definition io.h:43
#define outl(port, lng)
Emission d'un long sur un port.
Definition io.h:37
#define DBG_KERNEL_PCI
Definition debug.h:29
#define DBG_KERNEL_A_FAIRE
Definition debug.h:32
#define printk_debug(lvl, fmt, args...)
Definition debug.h:86
#define PCI_BAR_5
Definition pci.c:47
#define PCI_ID_EQUIPEMENT
Definition pci.c:39
#define PCI_INTERRUPTION
Definition pci.c:41
int PCINombreEquipements
: Une structure qui contient la description des équipements PCI détectés
Definition pci.c:59
uint16_t PCILireMot(uint8_t bus, uint8_t slot, uint8_t fonction, uint8_t offset)
Definition pci.c:93
#define PCI_ID_VENDEUR
Definition pci.c:38
#define MANUX_NB_BUS_PCI
: Le nombre de bus
Definition pci.c:33
int PCIObtenirProchainEquipement(uint16_t vendeur, uint16_t equipement, int precedent)
: récuperer l'identifiant du prochain équipement PCI
Definition pci.c:206
uint8_t PCILireOctet(uint8_t bus, uint8_t slot, uint8_t fonction, uint8_t offset)
Definition pci.c:106
#define PCI_AUCUN_VENDEUR
Definition pci.c:53
#define PCI_NB_EQUIP_PAR_BUS
Definition pci.c:18
void PCIEnumerationDesEquipements(void)
: recherche des équipements PCI disponibles
Definition pci.c:180
#define PCI_BAR_IO
Definition pci.c:52
PCIEquipement * PCIEquipementNumero(int n)
Definition pci.c:226
PCIEquipement PCIEquipements[MANUX_NB_MAX_EQUIPEMENTS_PCI]
Definition pci.c:61
#define PCI_CONFIG_ADDRESS
Les ports d'E/S de configuration du PCI.
Definition pci.c:24
#define PCI_BAR_0
Definition pci.c:42
#define PCI_CONFIG_DATA
Definition pci.c:27
uint32_t PCILireLong(uint8_t bus, uint8_t slot, uint8_t fonction, uint8_t offset)
: Lecture d'un mot sur le registre de config du PCI
Definition pci.c:75
: structure permettant d'identifier un équipement PCI
Definition pci.h:14
struct _PCIEquipement::_PCIConfigAddress configAddress
uint8_t interruption
Definition pci.h:18
uint32_t adresseES
Definition pci.h:19
uint16_t equipement
Definition pci.h:16
uint16_t vendeur
Definition pci.h:15