⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcicommon.c

📁 1. 8623L平台
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************** Copyright (c) 2003-2007 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This file is part of the EM86XX boot loader *//* * pcicommon.c * * by Ho Lee 02/05/2003 */#include "config.h"#include "uart.h"#include "util.h"#include "hardware.h"#include "io.h"#include "irqs.h"#include "pcicommon.h"//// global variables//struct my_pci_op *g_pciop = NULL;//// Initialization//int pci_init(struct my_pci_op *pop, int verbose){    if (pop) {        g_pciop = pop;        g_pciop->init(verbose);        return 0;    } else        return 1;}//// Basic//int pci_info(void){    if (g_pciop && g_pciop->info)        return g_pciop->info();        return 1;}unsigned int pci_select(int idsel){    if (g_pciop && g_pciop->select)        return g_pciop->select(idsel);        return 0;}//// Bus address translation//unsigned int virt_to_bus(unsigned int virt){    return (g_pciop && g_pciop->virt_to_bus) ? g_pciop->virt_to_bus(virt) : virt;}unsigned int bus_to_virt(unsigned int bus){    return (g_pciop && g_pciop->bus_to_virt) ? g_pciop->bus_to_virt(bus) : bus;}//// primitive PCI configuration I/O//#define PCI_READ_CONFIG_X(x, type, name) \    int pci_read_config_##name(unsigned int addr, unsigned type *data) \    { \        return (g_pciop && g_pciop->read_config_##name) ? g_pciop->read_config_##name(addr, data) : 1; \    }    #define PCI_WRITE_CONFIG_X(x, type, name) \    int pci_write_config_##name(unsigned int addr, unsigned int data) \    { \        return (g_pciop && g_pciop->write_config_##name) ? g_pciop->write_config_##name(addr, data) : 1; \    }PCI_READ_CONFIG_X(b, char, byte)PCI_READ_CONFIG_X(w, short, word)PCI_READ_CONFIG_X(l, int, dword)PCI_WRITE_CONFIG_X(b, char, byte)PCI_WRITE_CONFIG_X(w, short, word)PCI_WRITE_CONFIG_X(l, int, dword)//// primitive PCI I/O Access//    #define PCI_IN_X(x, type, name) \    unsigned type pci_in##x(unsigned int addr) \    { \        return (g_pciop && g_pciop->in_##name) ? g_pciop->in_##name(addr) : (unsigned type) -1; \    }    #define PCI_OUT_X(x, type, name) \    void pci_out##x(unsigned int data, unsigned int addr) \    { \        if (g_pciop && g_pciop->out_##name) \            g_pciop->out_##name(data, addr); \    }PCI_IN_X(b, char, byte)PCI_IN_X(w, short, word)PCI_IN_X(l, int, dword)PCI_OUT_X(b, char, byte)PCI_OUT_X(w, short, word)PCI_OUT_X(l, int, dword)//// primitive PCI Memory Access//    #define PCI_READ_X(x, type, name) \    unsigned type pci_read##x(unsigned int addr) \    { \        return (g_pciop && g_pciop->read_##name) ? g_pciop->read_##name(addr) : (unsigned type) -1; \    }    #define PCI_WRITE_X(x, type, name) \    void pci_write##x(unsigned int data, unsigned int addr) \    { \        if (g_pciop && g_pciop->write_##name) \            g_pciop->write_##name(data, addr); \    }PCI_READ_X(b, char, byte)PCI_READ_X(w, short, word)PCI_READ_X(l, int, dword)PCI_WRITE_X(b, char, byte)PCI_WRITE_X(w, short, word)PCI_WRITE_X(l, int, dword)//// PCI bus scan & dump// // restriction : This code does not support multi-function device//// scan every devices on the bus, and display the information of each deviceint pci_scan(void){    int i;    if (g_pciop == NULL)        return -1;    // Agent detection    for (i = g_pciop->idsel_start; i <= g_pciop->idsel_end; ++i) {        if (pci_select(i) != 0)            pci_dump_idsel(i, 0);    }    return 0;}struct my_pci_dev *pci_get_info(struct my_pci_dev *pdev, int readonly){    int i;    unsigned char hdr_type, latency, cacheline, irqpin, irqline;    unsigned short cmd, status;    unsigned int vendor_id, device_id, class, rev, romaddr, baseaddr, buses;        if (g_pciop == NULL)        return NULL;    g_pciop->read_config_byte(PCI_HEADER_TYPE, &hdr_type);    g_pciop->read_config_dword(PCI_VENDOR_ID, &vendor_id);    if (vendor_id == 0xffffffff || vendor_id == 0x00000000 || vendor_id == 0x0000ffff)        return NULL;        pdev->is_normal = ((hdr_type & 0x7f) == PCI_HEADER_TYPE_NORMAL) ? 1 : 0;    pdev->is_bridge = ((hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) ? 1 : 0;    pdev->is_cardbus = ((hdr_type & 0x7f) == PCI_HEADER_TYPE_CARDBUS) ? 1 : 0;        device_id = (vendor_id >> 16) & 0xffff;    vendor_id &= 0xffff;        g_pciop->read_config_word(PCI_COMMAND, &cmd);    g_pciop->read_config_word(PCI_STATUS, &status);        g_pciop->read_config_dword(PCI_CLASS_REVISION, &class);    rev = class & 0xff;    class >>= 8;    g_pciop->read_config_byte(PCI_LATENCY_TIMER, &latency);    g_pciop->read_config_byte(PCI_CACHE_LINE_SIZE, &cacheline);        g_pciop->read_config_byte(PCI_INTERRUPT_PIN, &irqpin);    g_pciop->read_config_byte(PCI_INTERRUPT_LINE, &irqline);    g_pciop->read_config_dword(PCI_ROM_ADDRESS, &romaddr);    g_pciop->read_config_dword(PCI_PRIMARY_BUS, &buses);        pdev->vendor_id = vendor_id;    pdev->device_id = device_id;    pdev->cmd = cmd;    pdev->status = status;    pdev->class = class;    pdev->progIF = class & 0xff;    pdev->subclass = (class >> 8) & 0xff;    pdev->classcode = (class >> 16) & 0xff;        pdev->rev = rev;    pdev->hdr_type = hdr_type;    pdev->latency = latency;    pdev->cacheline = cacheline;    pdev->irqpin = irqpin;    pdev->irqline = irqline;    pdev->romaddr = romaddr;        pdev->buses = buses;    pdev->primary_bus = buses & 0xff;    pdev->secondary_bus = (buses >> 8) & 0xff;    pdev->subordinate_bus = (buses >> 16) & 0xff;        for (i = 0; i < 6; ++i) {        g_pciop->read_config_dword(PCI_BASE_ADDRESS_0 + 4 * i, &baseaddr);        pdev->resource[i].isio = -1;        pdev->resource[i].start = pdev->base_addr[i] = baseaddr;        pdev->resource[i].size = 0;        if (baseaddr != 0) {            pdev->resource[i].isio = baseaddr & PCI_BASE_ADDRESS_SPACE_IO;            pdev->resource[i].start = baseaddr & (pdev->resource[i].isio ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK);        }                    if (!readonly) {            g_pciop->write_config_dword(PCI_BASE_ADDRESS_0 + 4 * i, 0xffffffff);            g_pciop->read_config_dword(PCI_BASE_ADDRESS_0 + 4 * i, &baseaddr);            if (baseaddr != 0) {                baseaddr &= (pdev->resource[i].isio ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK);                pdev->resource[i].size = ~baseaddr + 1;            }            g_pciop->write_config_dword(PCI_BASE_ADDRESS_0 + 4 * i, pdev->base_addr[i]);        }     }        if ((pdev->class >> 8) != PCI_CLASS_BRIDGE_PCI)         pdev->is_bridge = 0;    return pdev;}static char *s_strType[] = {    "Normal", "Brdige", "Cardbus" };static char *s_strCmd[] = {    "IO Enable", "Memory Enable", "Master", "Special",     "Invalidate", "VGA Palette", "Parity", "Wait",     "SERR", "Fast Back" };static char *s_strStatus[] = {    "", "", "", "",    "CAP List", "66MHz", "UDF", "Fast Back" };static char *s_strClassCode[] = {    "Reserved", "Disk", "Network", "Display",    "Multimedia", "Memory", "Bridge", "Communication",    "System Peripheral", "Input", "Docking station", "CPU",    "Serial Bus" };static char *s_strIoType[] = {    "Memory", "I/O" };static char *s_strMemType[] = {    "32 bit", "below 1M", "64 bit" };static char *s_strPrefetch[] = {    "Nonprefetchable", "Prefetchable" };#define INFOSTR(strarray, idx)  ((idx < (sizeof strarray / sizeof strarray[0])) ? strarray[idx] : "Unknown")#define INFOSTRBIT(strarray, data, max) \    for (i = 0, count = 0; data > 0 && (max <= 0 || i < max); ++i, data >>= 1) { \        if (data & 1) { \            if (count > 0) \                uart_printf(", "); \            uart_printf("%s", INFOSTR(strarray, i)); \            ++count; \        } \    }    void pci_dump(struct my_pci_dev *pdev){    int i, count, basecount;    unsigned int iotype, memtype, prefetch;    if (g_pciop == NULL)        return;    uart_printf("PCI ID select %d:\n", pdev->idsel);    // Vendor ID & Device ID        uart_printf("  Vendor ID = %04x, Device ID = %04x, Type = %02x (%s)\n",        pdev->vendor_id, pdev->device_id, pdev->hdr_type, INFOSTR(s_strType, pdev->hdr_type));    // Command & Status        uart_printf("  Command = %04x (", pdev->cmd);    INFOSTRBIT(s_strCmd, pdev->cmd, 0);    uart_printf(")\n");    uart_printf("  Status = %04x (", pdev->status);    INFOSTRBIT(s_strStatus, pdev->status, 8);    uart_printf(")\n");        // Class         uart_printf("  Class = %06x (", pdev->class);    uart_printf("Class = %s)\n", INFOSTR(s_strClassCode, pdev->classcode));    // Revision, Latency Timer, Cache Line Size        uart_printf("  Revision = %02x, Latency Timer = %02x, Cache Line Size = %02x\n",         pdev->rev, pdev->latency, pdev->cacheline);    // Interrupt    if (pdev->is_normal)         uart_printf("  Interrupt Line = %02x, Interrupt Pin = %02x\n",            pdev->irqline, pdev->irqpin);        // Base address        switch (pdev->hdr_type) {    case PCI_HEADER_TYPE_NORMAL :         basecount = 6;        break;    case PCI_HEADER_TYPE_BRIDGE :         basecount = 2;        break;    case PCI_HEADER_TYPE_CARDBUS :         basecount = 1;        break;    default :         basecount = 6;        break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -