'Debugging code to read pci/pcie slot type and slot Designation (also called slot number) & pci/pcie bus address
I have a really a simple code that reads file DMI in sys directory. And parse the memory data that is exposed by that file.
So my code is below. I am getting all wrong printf outputs for bus address and slot number also called slot designation. slot designation is a actual physical slot where pcie devices are by hand plugged in motherboard.
This is the function from a Linux utility called DMIDECODE
static void dmi_slot_segment_bus_func(uint16_t code1, uint8_t code2, uint8_t code3)
{
/* 7.10.8 */
if (!(code1 == 0xFFFF && code2 == 0xFF && code3 == 0xFF))
printf("Bus Address %04x:%02x:%02x.%x\n",
code1, code2, code3 >> 3, code3 & 0x7);
}
This is a rather a simple function that simple takes word for Segment Group Number and two parameters of byte length each. second parameter is byte representing Bus number and last last parameter function number at offset arr+0x10 which is 16 I believe in decimal. But my bus numbers are weird also the slot numbers and slot type makes absolute garbage like 32 for slot type and 20 for slot number this is the output of program on my system
type 9
handle 8
length 17
slot 20
slot type 31
bus 3
function 4
segment a
+b0 a+
Bus Address 00ba:03:00.4
type 9
handle 9
length 17
slot 20
slot type 32
bus 3
function 4
segment d
+ab d+
Bus Address 00b8:03:00.4
type 9
handle a
length 17
slot 20
slot type 33
bus 3
function 4
segment 5
+6 5+
Bus Address 000b:03:00.4
type 9
handle b
length 17
slot 20
slot type 34
bus 83
function 20
segment 42
+41 42+
Bus Address 0083:53:04.0
(( 4 ))
root@fawad:/ho
So this is my code in C/C++
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <time.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
struct structure
{
uint8_t type;
uint8_t length;
uint16_t handle;
};
int count=0;
#define WORD(x) (uint16_t)((x)[0] + ((x)[1] << 8))
static void dmi_slot_segment_bus_func(uint16_t code1, uint8_t code2, uint8_t code3)
{
/* 7.10.8 */
if (!(code1 == 0xFFFF && code2 == 0xFF && code3 == 0xFF))
printf("Bus Address %04x:%02x:%02x.%x\n",
code1, code2, code3 >> 3, code3 & 0x7);
}
//dmidecode -t 9 | grep "desig | type 9"
void process_dmi(char *arr,long n,struct structure *my)
{
int i=0;
while(i<n)
{
struct structure *m=(struct structure *)&arr[i];
i=i+m->length;
int j=i;
if(m->type==9)
{
printf("type %d\n",m->type);
printf("handle %x\n",m->handle);
printf("length %d\n",m->length);
printf("slot %x\n",arr[i+4]&0b11111111);
printf("slot type %x\n",arr[i+5]&0b11111111);
printf("bus %d\n",arr[i+15]&0b11111111);
printf("function %x\n",arr[i+16]&0b11111111);
printf("segment %x\n",arr[i+14]&0b1111111111111111);
printf("+%x %x+ \n",arr[i+13]&0b11111111,(arr[i+14]&0b11111111));
dmi_slot_segment_bus_func(((arr[i+13])&0b11111111)+(arr[i+14]&0b11111111), arr[i+0x0F], arr[i+0x10]);
count++;
}
while(*(arr+j)!=0 || *(arr+j+1)!=0)
{
j++;
}
if(j>i)
{
i=j+2;
}
else
i++;
}
printf("(( %d ))\n",count);
}
int main()
{
struct stat stats;
int fd=open("/sys/firmware/dmi/tables/smbios_entry_point",O_RDONLY);
if(fd<=0)
{
printf("fd %d %d\n",fd,errno);
exit(0);
}
char *buffer=malloc(sizeof(char )*1000);
int x=read(fd,buffer,1000);
if(x<0)
exit(0);
printf("struct SMBIOS entry point\n");
printf("+-_%d______________________________\n",x);
int j=0;
while(j<100)
{
if(buffer[j]=='_' && buffer[j+1]=='S' && buffer[j+2]=='M' && buffer[j+3]=='_')
{
printf("~%d\n",j);
//buffer=buffer+5;
int i=j;
int k=0;
while(i<31)
{
i++;
}
}
j++;
}
int k=0;
printf("+__________________________________________________\n");
struct stat stats_dmi;
int ret=0;
if ((ret=stat("/sys/firmware/dmi/tables/DMI", &stats_dmi)) == 0)
{
printf("DMI size %ld\n",stats_dmi.st_size);
}
else
{
printf("ret = %d\n",ret);
}
int fd_dmi=open("/sys/firmware/dmi/tables/DMI",O_RDONLY);
if(fd_dmi<=0)
{
printf("fd %d %d\n",fd_dmi,errno);
exit(0);
}
char *buffer_dmi=malloc(sizeof(char )*stats_dmi.st_size);
read(fd_dmi,buffer_dmi,stats_dmi.st_size+1);
printf("struct DMI entry point\n");
printf("+_______________________________\n");
struct structure *my_struct;
process_dmi(buffer_dmi,stats_dmi.st_size,my_struct);
return 0;
}
Also the lspci buses are like which does not match with my output busses addresses. Also in dmidecode devices are slotted as slot 1, I am getting 20 for slot or 22 and so on. I don't get it.
00:00.0
00:01.0
00:02.0
00:06.0
00:16.0
00:16.2
00:16.3
00:19.0
00:1a.0
00:1b.0
00:1c.0
00:1c.4
00:1c.6
00:1d.0
00:1e.0
00:1f.0
00:1f.2
00:1f.3
00:1f.5
I dmidecode prints SMBIOS 2.7
There is a doc that where I am getting offsets of different DMI fields DSP0134_3.1.0.pdf its available by simple googling.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
