代码语言
.
CSharp
.
JS
Java
Asp.Net
C
MSSQL
PHP
Css
PLSQL
Python
Shell
EBS
ASP
Perl
ObjC
VB.Net
VBS
MYSQL
GO
Delphi
AS
DB2
Domino
Rails
ActionScript
Scala
代码分类
文件
系统
字符串
数据库
网络相关
图形/GUI
多媒体
算法
游戏
Jquery
Extjs
Android
HTML5
菜单
网页交互
WinForm
控件
企业应用
安全与加密
脚本/批处理
开放平台
其它
【
C
】
pcie配置空间读写应用程序
作者:
moon146
/ 发布于
2013/10/23
/
690
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/io.h> #include <sys/mman.h> #define PCI_CTRL_PORT 0xCF8 #define PCI_DATA_PORT 0xCFC #define PCI_DEV_NUM 0x0 #define PRI_BUS_NUM 0x18 #define SEC_BUS_NUM 0x19 #define SUB_BUS_NUM 0x1a #define PCI_MCONF_CTRL 0x260 #define PCI_MCONF_BUFF 0x264 #define EEPROM_BIT 16 #define PLX8632_DEV 0x863210B5 #define BUS_BIT 20 #define SLOT_BIT 15 #define FUNC_BIT 12 #define REG_BIT 2 #define EN_BIT 0 #define PCIE_CONF_SIZE 0x1000 #define PCIEXBAR_ADDR 0x80000000 typedef struct { unsigned char bus; unsigned char slot; unsigned char func; } pci_dev_t; static pci_dev_t ninja_slot[3] = { {0, 3, 0}, {0, 3, 2}, {0, 2, 2}, }; int mem_fd = -1; volatile char * mem = NULL; unsigned int map_pci_config_space(unsigned char bus, unsigned char slot, unsigned char func) { unsigned long phyaddr; unsigned int len; mem_fd = open("/dev/mem", O_RDWR); if(mem_fd < 0) { printf("file /dev/mem open error\n"); return 1; } phyaddr = (PCIEXBAR_ADDR) | (bus << BUS_BIT) | (slot << SLOT_BIT) | (func << FUNC_BIT); len = PCIE_CONF_SIZE; //printf("phyaddr %lx, len %x\n", phyaddr, len); mem = (volatile char *) mmap(0, len, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, phyaddr); if((char *) MAP_FAILED == mem) { printf("mmap failed %d, pbyaddr : 0x%lx, len : 0xx\n", bus, phyaddr, len); return 1; } return 0; } unsigned int unmap_pci_config_space(void) { unsigned int len = PCIE_CONF_SIZE; if (mem != NULL) { munmap((void *)mem, len); mem = NULL; } close(mem_fd); return 0; } /* for offset < 0xff */ static unsigned char read_pci_config_8(unsigned char bus, unsigned char slot, unsigned char func, unsigned char offset) { unsigned char v; outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, PCI_CTRL_PORT); v = inb(PCI_DATA_PORT + (offset&3)); return v; } #if 0 static unsigned short read_pci_config_16(unsigned char bus, unsigned char slot, unsigned char func, unsigned char offset) { unsigned short v; outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, PCI_CTRL_PORT); v = inw(PCI_DATA_PORT + (offset&2)); return v; } static unsigned int read_pci_config_32(unsigned char bus, unsigned char slot, unsigned char func, unsigned char offset) { unsigned int v; outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, PCI_CTRL_PORT); v = inl(PCI_DATA_PORT); return v; } static void write_pci_config_8(unsigned char bus,unsigned char slot, unsigned char func, unsigned char offset, unsigned char val) { outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, PCI_CTRL_PORT); outb(val, PCI_DATA_PORT + (offset&3)); } static void write_pci_config_16(unsigned char bus,unsigned char slot, unsigned char func, unsigned char offset, unsigned char val) { outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, PCI_CTRL_PORT); outw(val, PCI_DATA_PORT + (offset&2)); } static void write_pci_config_32(unsigned char bus, unsigned char slot, unsigned char func, unsigned char offset, unsigned int val) { outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, PCI_CTRL_PORT); outl(val, PCI_DATA_PORT); } #endif /* for offset 0 - 0x1000 */ static unsigned int pci_mmconfig_write_32(unsigned short offset, unsigned int val) { if (mem == NULL) return 1; *(volatile unsigned int *)(mem + (offset << REG_BIT)/sizeof(unsigned int)) = val; return 0; } static unsigned int pci_mmconfig_read_32(unsigned short offset, unsigned int * val) { if (mem == NULL) return 1; *val = *(volatile unsigned int *)(mem + (offset << REG_BIT)/sizeof(unsigned int)); return 0; } unsigned int is_valid_slot(unsigned int slot_num, unsigned char * bus) { pci_dev_t * pci_dev; unsigned char sec_bus; unsigned char sub_bus; if (slot_num > 3) return 1; pci_dev = &ninja_slot[slot_num]; sec_bus = read_pci_config_8(pci_dev->bus, pci_dev->slot, pci_dev->func, SEC_BUS_NUM); sub_bus = read_pci_config_8(pci_dev->bus, pci_dev->slot, pci_dev->func, SUB_BUS_NUM); //printf("%x [%x - %x]\n", slot_num, sec_bus, sub_bus); if ((sub_bus - sec_bus) == 10) { *bus = sec_bus; return 0; } return 1; } static unsigned int plx8632_eeprom_read(unsigned int slot_num, unsigned char * board_type) { unsigned char bus; unsigned int eeprom_addr; unsigned int version[64], ver_start; //unsigned char board_type[16]; unsigned int val; unsigned int count; int i; if (is_valid_slot(slot_num, &bus) == 0) { if (map_pci_config_space(bus, 0, 0)) { printf("map pci config space error.\n"); return 1; } if (pci_mmconfig_read_32(PCI_DEV_NUM, &val)) { printf("mmconfig read error.\n"); return 1; } if (val != PLX8632_DEV) { printf("it is not plx8632.\n"); return 1; } if (pci_mmconfig_read_32(PCI_MCONF_CTRL, &val)) { printf("mmconfig read error.\n"); return 1; } if ((val & (1 << EEPROM_BIT)) == 0) { printf("no eeprom here.\n"); return 1; } eeprom_addr = (val & 0xffff0000) | (0x3 << 13); for( i = 0; i < 64; i++) { if (pci_mmconfig_write_32(PCI_MCONF_CTRL, eeprom_addr)) { printf("get eeprom address error.\n"); return 1; } //wait command executed complete count = 0; do { if (pci_mmconfig_read_32(PCI_MCONF_CTRL, &val)) { printf("read status error.\n"); return 1; } usleep(100); count++; } while((((val >> 18) & 0x1) && (count < 1000))); if(count >= 1000) { printf("read EEPROM timeout\n"); return 1; } if(pci_mmconfig_read_32(PCI_MCONF_BUFF, &val)) { printf("read EEPROM value error.\n"); return 1; } version[i] = val; if( val == 0xffffffff) break; eeprom_addr++; } // eeprom data : [0xaa55] [data_len] [register_data] [serial_num] ver_start = (version[0] >> 16)/4 + 1; if ((version[0] >> 16) % 4) { int j = 0; int k = 0; *(unsigned char *)(board_type + k++) = ((version[ver_start] >> 16) & 0xff); *(unsigned char *)(board_type + k++) = ((version[ver_start] >> 24) & 0xff); for(i = 1;i < 4; i++) { for(j = 0;j < 32; j+=8) *(unsigned char *)(board_type + k++) = ((version[ver_start+i] >> j) & 0xff); } *(unsigned char *)(board_type + k++) = (version[ver_start+i]) & 0xff; *(unsigned char *)(board_type + k++) = (version[ver_start+i]>>8) & 0xff; } else { int j = 0; int k = 0; for (i = 0;i < 4; i++) { for (j = 0;j < 32; j+=8) *(unsigned char *)(board_type + k++) = (version[ver_start + i] >> j) & 0xff; } } if((board_type[12] == 0x0) && (board_type[13] == 0x0) && (board_type[14] == 0x0) && (board_type[15] == 0x0)) { printf("there is no hardware version available,please to have a check\n"); return 1; } //printf("Board type:s Hardware Version: %d.%d.%d.%d\n", board_type, board_type[12], board_type[13], board_type[14], board_type[15]); unmap_pci_config_space(); return 0; } else { printf("slot is invalid\n"); return 1; } } int main(void) { unsigned char board[16]; iopl(3); printf("slot0\n"); if (0 == plx8632_eeprom_read(0, board)) { printf("s\n", board); printf("%d %d %d %d\n", board[12], board[13], board[14], board[15]); } printf("slot1\n"); if (0 == plx8632_eeprom_read(1, board)) { printf("s\n", board); printf("%d %d %d %d\n", board[12], board[13], board[14], board[15]); } printf("slot2\n"); if (0 == plx8632_eeprom_read(2, board)) { printf("s\n", board); printf("%d %d %d %d\n", board[12], board[13], board[14], board[15]); } return 0; }
试试其它关键字
pcie
同语言下
.
获取手机通讯录 iOS去除数字以外的所有字符
.
异步加载音乐等资源
.
交通罚单管理系统
.
freemark实现,简单的替换
.
计算斐波那契数列
.
base64解码 包括解码长度
.
图像显示
.
冒泡排序
.
输入十进制数,输出指定进制
.
链式栈
可能有用的
.
C#实现的html内容截取
.
List 切割成几份 工具类
.
SQL查询 多列合并成一行用逗号隔开
.
一行一行读取txt的内容
.
C#动态修改文件夹名称(FSO实现,不移动文件)
.
c# 移动文件或文件夹
.
c#图片添加水印
.
Java PDF转换成图片并输出给前台展示
.
网站后台修改图片尺寸代码
.
处理大图片在缩略图时的展示
moon146
贡献的其它代码
(
1
)
.
pcie配置空间读写应用程序
Copyright © 2004 - 2024 dezai.cn. All Rights Reserved
站长博客
粤ICP备13059550号-3