cos2000v2/lib/pci.c

148 lines
4.2 KiB
C

/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */
#include "asm.h"
#include "types.h"
#include "pci.h"
#include "PCI/class.c"
#define MAX_BUS_SCAN 256
#define MAX_DEVICE_SCAN 32
#define MAX_FUNCTION_SCAN 8
/*******************************************************************************/
/* Retourne une chaine correspondant à l'ID class/subclass PCI */
u8 *pcigetclassname(const pcidev * device)
{
pciclass *class = NULL;
if (device == NULL)
{
return NULL;
}
if (device->base_class == 0xff)
{
return "Unassigned class";
}
class = classcodes[device->base_class];
if (!class)
{
return "Unknowned class";
}
while (class->name != NULL)
{
if (class->number == device->sub_class)
{
return class->name;
}
class++;
}
return "Unknowned class";
}
/*******************************************************************************/
/* Récupère les identifiants vendeur / periphérique du periphérique PCI donnée */
pcidevmini getPCImininfo(const u8 bus, const u8 dev, const u8 function)
{
pcidevmini result;
if ((result.vendor_id =
pciConfigReadWord(bus, dev, function, 0x0)) != 0xFFFF)
{
result.device_id =
pciConfigReadWord(bus, dev, function, 0x2);
}
return result;
}
/*******************************************************************************/
/* Récupère toutes les informations du periphérique PCI donnée */
bool getPCInfo(pcidev * device, const u8 bus, const u8 dev,
const u8 function)
{
if ((device->vendor_id =
pciConfigReadWord(bus, dev, function, 0x0)) != 0xFFFF)
{
u16 temp;
device->device_id =
pciConfigReadWord(bus, dev, function, 0x2);
device->command =
pciConfigReadWord(bus, dev, function, 0x4);
device->status =
pciConfigReadWord(bus, dev, function, 0x6);
temp = pciConfigReadWord(bus, dev, function, 0x8);
device->revision_id = temp & 0xFF;
device->interface = temp >> 8;
temp = pciConfigReadWord(bus, dev, function, 0xA);
device->sub_class = temp & 0xFF;
device->base_class = temp >> 8;
temp = pciConfigReadWord(bus, dev, function, 0xC);
device->cache_line_size = temp & 0xFF;
device->latency_timer = temp >> 8;
temp = pciConfigReadWord(bus, dev, function, 0xE);
device->header_type = temp & 0xFF;
device->bist = temp >> 8;
return true;
}
else
return false;
}
/*******************************************************************************/
/* Récupère les informations sur le periphérique PCI donnée */
u16 pciConfigReadWord(const u8 bus, const u8 dev, const u8 function,
const u8 offset)
{
u16 tmp = 0;
u32 addr =
(0x80000000 | (bus << 16) | (dev << 11) | (function << 8) |
(offset & 0xFC));
outd(0xCF8, addr);
tmp = (u16) ((ind(0xCFC) >> ((offset & 2) * 8)) & 0xffff);
return tmp;
}
/*******************************************************************************/
/* Scan le bus PCI et affiche les périphériques */
void scanPCImini(void)
{
u16 bus, device, function;
pcidevmini result;
for (bus = 0; bus < MAX_BUS_SCAN; ++bus)
for (device = 0; device < MAX_DEVICE_SCAN; ++device)
for (function = 0; function < MAX_FUNCTION_SCAN;
++function)
{
result = getPCImininfo(bus, device,
function);
if (result.vendor_id != 0xFFFF)
printf("Bus:%hx Dev:%hx Func:%hx %hx:%hx\r\n", bus, device, function, result.vendor_id, result.device_id);
}
return;
}
/*******************************************************************************/
/* Scan le bus PCI et affiche les périphériques */
void scanPCI(void)
{
u16 bus, device, function;
pcidev result;
for (bus = 0; bus < MAX_BUS_SCAN; ++bus)
for (device = 0; device < MAX_DEVICE_SCAN; ++device)
for (function = 0; function < MAX_FUNCTION_SCAN;
++function)
if (getPCInfo
(&result, bus, device, function))
printf("Bus:%hx Dev:%hx Func:%hx %hx:%hx ->%s\r\n", bus, device, function, result.vendor_id, result.device_id, pcigetclassname(&result));
return;
}
/*******************************************************************************/