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

📄 pci.c

📁 BIOS emulator and interface to Realmode X86 Emulator Library Can emulate a PCI Graphic Controller V
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright 1999 Egbert Eich * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of the authors not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission.  The authors makes no representations * about the suitability of this software for any purpose.  It is provided * "as is" without express or implied warranty. * * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */#include "debug.h"#include <fcntl.h>#include <unistd.h>#include <malloc.h>#include <stdio.h>#include <sys/mman.h>#include <sys/types.h>#include <sys/stat.h>#include <string.h>#include "AsmMacros.h"#include "pci.h"/* * I'm rather simple mindend - therefore I do a poor man's * pci scan without all the fancy stuff that is done in * scanpci. However that's all we need. */PciStructPtr PciStruct = NULL;PciBusPtr PciBuses = NULL;PciStructPtr CurrentPci = NULL;int pciMaxBus = 0;static CARD32 PciCfg1Addr;static void readConfigSpaceCfg1(CARD32 bus, CARD32 dev, CARD32 func,				CARD32 *reg);static int checkSlotCfg1(CARD32 bus, CARD32 dev, CARD32 func);static int checkSlotCfg2(CARD32 bus, int dev);static void readConfigSpaceCfg2(CARD32 bus, int dev, CARD32 *reg);static CARD8 interpretConfigSpace(CARD32 *reg,CARD32 *pcibuses, int busidx,				  CARD8 dev, CARD8 func);static CARD32 findBIOSMap(CARD32 *biosSize);static void restoreMem(void);#ifdef __alpha__#define PCI_BUS_FROM_TAG(tag)  (((tag) & 0x00ff0000) >> 16)#define PCI_DFN_FROM_TAG(tag) (((tag) & 0x0000ff00) >> 8)#include <asm/unistd.h>CARD32axpPciCfgRead(CARD32 tag){    int bus, dfn;    CARD32 val = 0xffffffff;        bus = PCI_BUS_FROM_TAG(tag);    dfn = PCI_DFN_FROM_TAG(tag);        syscall(__NR_pciconfig_read, bus, dfn, tag & 0xff, 4, &val);    return(val);}voidaxpPciCfgWrite(CARD32 tag, CARD32 val){    int bus, dfn;        bus = PCI_BUS_FROM_TAG(tag);    dfn = PCI_DFN_FROM_TAG(tag);        syscall(__NR_pciconfig_write, bus, dfn, tag & 0xff, 4, &val);}static CARD32 (*readPci)(CARD32 reg) = axpPciCfgRead;static void (*writePci)(CARD32 reg, CARD32 val) = axpPciCfgWrite;#elsestatic CARD32 readPciCfg1(CARD32 reg);static void writePciCfg1(CARD32 reg, CARD32 val);static CARD32 readPciCfg2(CARD32 reg);static void writePciCfg2(CARD32 reg, CARD32 val);static CARD32 (*readPci)(CARD32 reg) = readPciCfg1;static void (*writePci)(CARD32 reg, CARD32 val) = writePciCfg1;#endif#if defined(__alpha__) || defined(__sparc__)#define PCI_EN 0x00000000#else#define PCI_EN 0x80000000#endifstatic int numbus;static int hostbridges = 1;static unsigned long pciMinMemReg = ~0;voidscan_pci(void){    unsigned short configtype;        CARD32 reg[64];    CARD32 pcibuses[16];    int busidx;    CARD8 cardnum;    CARD8 func;        int idx;        int i;    PciStructPtr pci1;    PciBusPtr pci_b1,pci_b2;    #if defined(__alpha__) || defined(__powerpc__) || defined(__sparc__)    configtype = 1;#else    CARD8 tmp1, tmp2;    CARD32 tmp32_1, tmp32_2;    outb(PCI_MODE2_ENABLE_REG, 0x00);    outb(PCI_MODE2_FORWARD_REG, 0x00);    tmp1 = inb(PCI_MODE2_ENABLE_REG);    tmp2 = inb(PCI_MODE2_FORWARD_REG);    if ((tmp1 == 0x00) && (tmp2 == 0x00)) {		configtype = 2;		readPci = readPciCfg2;		writePci = writePciCfg2;		P_printf("PCI says configuration type 2\n");    } else {		tmp32_1 = inl(PCI_MODE1_ADDRESS_REG);		outl(PCI_MODE1_ADDRESS_REG, PCI_EN);		tmp32_2 = inl(PCI_MODE1_ADDRESS_REG);		outl(PCI_MODE1_ADDRESS_REG, tmp32_1);		if (tmp32_2 == PCI_EN) {			configtype = 1;			P_printf("PCI says configuration type 1\n");		} else {			fprintf(stderr,"No PCI !\n");			return;		}    }#endif        if (configtype == 1) {		P_printf("PCI probing configuration type 1\n");		pcibuses[0] = 0;		numbus = 1;		busidx = 0;		idx = 0;		do {			P_printf("\nProbing for devices on PCI bus %d:\n", busidx);			for (cardnum = 0; cardnum < MAX_DEV_PER_VENDOR_CFG1; cardnum++) {				func = 0;				do {					/* loop over the different functions, if present */					if (!checkSlotCfg1(pcibuses[busidx],cardnum,func))						break;					readConfigSpaceCfg1(pcibuses[busidx],cardnum,func,reg);		    					func = interpretConfigSpace(reg,pcibuses,busidx,												cardnum,func);		    					if (idx++ > MAX_PCI_DEVICES)						continue;				} while (func < 8);			}		} while (++busidx < numbus);#if defined(__alpha__) || defined(__powerpc__) || defined(__sparc__)		/* don't use outl()  ;-) */#else		outl(PCI_MODE1_ADDRESS_REG, 0);#endif    } else {		int slot;			P_printf("PCI probing configuration type 2\n");		pcibuses[0] = 0;		numbus = 1;		busidx = 0;		idx = 0;		do {			for (slot=0xc0; slot<0xd0; i++) {				if (!checkSlotCfg2(pcibuses[busidx],slot))					break;				readConfigSpaceCfg2(pcibuses[busidx],slot,reg);						interpretConfigSpace(reg,pcibuses,busidx,									 slot,0);				if (idx++ > MAX_PCI_DEVICES)					continue;			}		}  while (++busidx < numbus);    }            pciMaxBus = numbus - 1;    P_printf("Max buses in system: %i\n",pciMaxBus + 1);    P_printf("Min PCI mem address: 0x%lx\n",pciMinMemReg);        /* link buses */    pci_b1 = PciBuses;    while (pci_b1) {		pci_b2 = PciBuses;		pci_b1->pBus = NULL;		while (pci_b2) {			if (pci_b1->primary == pci_b2->secondary)				pci_b1->pBus = pci_b2;			pci_b2 = pci_b2->next;		}		pci_b1 = pci_b1->next;    }    pci1 = PciStruct;    while (pci1) {		pci_b2 = PciBuses;		pci1->pBus = NULL;		while (pci_b2) {			if (pci1->bus == pci_b2->secondary)				pci1->pBus = pci_b2;			pci_b2 = pci_b2->next;		}		pci1 = pci1->next;    }    if (RESORT) {		PciStructPtr tmp = PciStruct, tmp1;		PciStruct = NULL;		while (tmp) {			tmp1 = tmp->next;			tmp->next = PciStruct;			PciStruct = tmp;			tmp = tmp1;		}    }    CurrentPci = PciStruct;}#ifndef __alpha__static CARD32readPciCfg1(CARD32 reg){    CARD32 val;        outl(PCI_MODE1_ADDRESS_REG, reg);    val = inl(PCI_MODE1_DATA_REG);    outl(PCI_MODE1_ADDRESS_REG, 0);    P_printf("reading: 0x%x from 0x%x\n",val,reg);    return val;}static voidwritePciCfg1(CARD32 reg, CARD32 val){    P_printf("writing: 0x%x to 0x%x\n",val,reg);    outl(PCI_MODE1_ADDRESS_REG, reg);    outl(PCI_MODE1_DATA_REG,val);    outl(PCI_MODE1_ADDRESS_REG, 0);}static CARD32readPciCfg2(CARD32 reg){    CARD32 val;    CARD8 bus = (reg >> 16) & 0xff;    CARD8 dev = (reg >> 11) & 0x1f;    CARD8 num = reg & 0xff;        outb(PCI_MODE2_ENABLE_REG, 0xF1);    outb(PCI_MODE2_FORWARD_REG, bus);    val = inl((dev << 8) + num);    outb(PCI_MODE2_ENABLE_REG, 0x00);    P_printf("reading: 0x%x from 0x%x\n",val,reg);    return val;}static voidwritePciCfg2(CARD32 reg, CARD32 val){    CARD8 bus = (reg >> 16) & 0xff;    CARD8 dev = (reg >> 11) & 0x1f;    CARD8 num = reg & 0xff;    P_printf("writing: 0x%x to 0x%x\n",val,reg);    outb(PCI_MODE2_ENABLE_REG, 0xF1);    outb(PCI_MODE2_FORWARD_REG, bus);    outl((dev << 8) + num,val);    outb(PCI_MODE2_ENABLE_REG, 0x00);}#endifvoidpciVideoDisable(void){    /* disable VGA routing on bridges */    PciBusPtr pbp = PciBuses;    PciStructPtr pcp = PciStruct;        while (pbp) {		writePci(pbp->Slot.l | 0x3c, pbp->bctl & ~(CARD32)(8<<16));		pbp = pbp->next;    }    /* disable display devices */    while (pcp) {		writePci(pcp->Slot.l | 0x04, pcp->cmd_st & ~(CARD32)3);		writePci(pcp->Slot.l | 0x30, pcp->RomBase & ~(CARD32)1);		pcp = pcp->next;    }}voidpciVideoRestore(void){    /* disable VGA routing on bridges */    PciBusPtr pbp = PciBuses;    PciStructPtr pcp = PciStruct;        while (pbp) {		writePci(pbp->Slot.l | 0x3c, pbp->bctl);		pbp = pbp->next;    }    /* disable display devices */    while (pcp) {		writePci(pcp->Slot.l | 0x04, pcp->cmd_st);		writePci(pcp->Slot.l | 0x30, pcp->RomBase);		pcp = pcp->next;    }}voidEnableCurrent(){    PciBusPtr pbp;    PciStructPtr pcp = CurrentPci;        pciVideoDisable();        pbp = pcp->pBus;    while (pbp) { /* enable bridges */		writePci(pbp->Slot.l | 0x3c, pbp->bctl | (CARD32)(8<<16));		pbp = pbp->pBus;    }    writePci(pcp->Slot.l | 0x04, pcp->cmd_st | (CARD32)3);    writePci(pcp->Slot.l | 0x30, pcp->RomBase | (CARD32)1);}CARD8PciRead8(int offset, CARD32 Slot){    int shift = offset & 0x3;    offset = offset & 0xFC;    return ((readPci(Slot | offset) >> (shift << 3)) & 0xff);}CARD16PciRead16(int offset, CARD32 Slot){    int shift = offset & 0x2;    offset = offset & 0xFC;    return ((readPci(Slot | offset) >> (shift << 3)) & 0xffff);}CARD32PciRead32(int offset, CARD32 Slot){    offset = offset & 0xFC;    return (readPci(Slot | offset));}voidPciWrite8(int offset, CARD8 byte, CARD32 Slot){    CARD32 val;    int shift = offset & 0x3;    offset = offset & 0xFC;    val = readPci(Slot | offset);    val &= ~(CARD32)(0xff << (shift << 3));    val |= byte << (shift << 3);    writePci(Slot | offset, val);}voidPciWrite16(int offset, CARD16 word, CARD32 Slot){    CARD32 val;    int shift = offset & 0x2;    offset = offset & 0xFC;    val = readPci(Slot | offset);    val &= ~(CARD32)(0xffff << (shift << 3));    val |= word << (shift << 3);    writePci(Slot | offset, val);}voidPciWrite32(int offset, CARD32 lg, CARD32 Slot){    offset = offset & 0xFC;    writePci(Slot | offset, lg);}int

⌨️ 快捷键说明

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