2018-11-08 22:12:51 +01:00
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* COS2000 - Compatible Operating System - LGPL v3 - Hord<72> Nicolas */
|
|
|
|
|
/* */
|
|
|
|
|
|
|
|
|
|
#include "asm.h"
|
|
|
|
|
#include "types.h"
|
|
|
|
|
#include "pci.h"
|
2018-11-12 09:49:00 +01:00
|
|
|
|
#include "PCI/class.c"
|
2018-11-08 22:12:51 +01:00
|
|
|
|
|
|
|
|
|
#define MAX_BUS_SCAN 256
|
|
|
|
|
#define MAX_DEVICE_SCAN 32
|
|
|
|
|
#define MAX_FUNCTION_SCAN 8
|
|
|
|
|
|
2018-11-12 09:49:00 +01:00
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Retourne une chaine correspondant <20> 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";
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-08 22:12:51 +01:00
|
|
|
|
/*******************************************************************************/
|
2018-11-09 16:44:56 +01:00
|
|
|
|
/* R<>cup<75>re les identifiants vendeur / periph<70>rique du periph<70>rique PCI donn<6E>e */
|
2018-11-08 22:12:51 +01:00
|
|
|
|
|
2018-11-12 09:49:00 +01:00
|
|
|
|
pcidevmini getPCImininfo(const u8 bus, const u8 dev, const u8 function)
|
2018-11-08 22:12:51 +01:00
|
|
|
|
{
|
2018-11-12 09:49:00 +01:00
|
|
|
|
pcidevmini result;
|
|
|
|
|
if ((result.vendor_id = pciConfigReadWord(bus,dev,function,0x0)) != 0xFFFF) {
|
|
|
|
|
result.device_id = pciConfigReadWord(bus,dev,function,0x2);
|
2018-11-09 16:44:56 +01:00
|
|
|
|
}
|
2018-11-08 22:12:51 +01:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-12 09:49:00 +01:00
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* R<>cup<75>re toutes les informations du periph<70>rique PCI donn<6E>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;
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-09 16:44:56 +01:00
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* R<>cup<75>re les informations sur le periph<70>rique PCI donn<6E>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;
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-08 22:12:51 +01:00
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Scan le bus PCI et affiche les p<>riph<70>riques */
|
|
|
|
|
|
2018-11-12 09:49:00 +01:00
|
|
|
|
void scanPCImini(void)
|
2018-11-08 22:12:51 +01:00
|
|
|
|
{
|
2018-11-09 16:44:56 +01:00
|
|
|
|
u16 bus,device,function;
|
2018-11-12 09:49:00 +01:00
|
|
|
|
pcidevmini result;
|
2018-11-08 22:12:51 +01:00
|
|
|
|
for (bus=0; bus<MAX_BUS_SCAN; ++bus)
|
|
|
|
|
for (device=0; device<MAX_DEVICE_SCAN; ++device)
|
|
|
|
|
for (function=0; function<MAX_FUNCTION_SCAN; ++function)
|
|
|
|
|
{
|
2018-11-09 16:44:56 +01:00
|
|
|
|
result = getPCImininfo(bus,device,function);
|
2018-11-12 09:49:00 +01:00
|
|
|
|
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);
|
2018-11-08 22:12:51 +01:00
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
2018-11-12 09:49:00 +01:00
|
|
|
|
/* Scan le bus PCI et affiche les p<>riph<70>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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|