📄 pci.c
字号:
mapPciRom(void){ unsigned long RomBase = 0; int mem_fd; unsigned char *mem, *ptr; unsigned char *scratch = NULL; int length = 0; CARD32 biosSize = 0x1000000; if (FIX_ROM) { RomBase = findBIOSMap(&biosSize); if (!RomBase) { fprintf(stderr,"Cannot remap BIOS of %i:%i:%i " "- trying preset address\n",CurrentPci->bus,CurrentPci->dev, CurrentPci->func); RomBase = CurrentPci->RomBase & ~(CARD32)0xFF; } } else { RomBase = CurrentPci->RomBase & ~(CARD32)0xFF; if (~RomBase + 1 < biosSize || !RomBase) RomBase = findBIOSMap(&biosSize); } P_printf("RomBase: 0x%lx\n",RomBase); if ((mem_fd = open(MEM_FILE,O_RDWR))<0) { perror("opening memory"); restoreMem(); return (0); } PciWrite32(0x30,RomBase | 1,CurrentPci->Slot.l);#ifdef __alpha__ mem = ptr = (unsigned char *)mmap(0, biosSize, PROT_READ, MAP_SHARED, mem_fd, RomBase | _bus_base());#else mem = ptr = (unsigned char *)mmap(0, biosSize, PROT_READ, MAP_SHARED, mem_fd, RomBase);#endif#ifdef PRINT_PCI dprint((unsigned long)ptr,0x30);#endif while ( *ptr == 0x55 && *(ptr+1) == 0xAA) { unsigned short data_off = *(ptr+0x18) | (*(ptr+0x19)<< 8); unsigned char *data = ptr + data_off; unsigned char type; int i; if (*data!='P' || *(data+1)!='C' || *(data+2)!='I' || *(data+3)!='R') { break; } type = *(data + 0x14); P_printf("data segment in BIOS: 0x%x, type: 0x%x ",data_off,type); if (type != 0) { /* not PC-AT image: find next one */ unsigned int image_length; unsigned char indicator = *(data + 0x15); if (indicator & 0x80) /* last image */ break; image_length = (*(data + 0x10) | (*(data + 0x11) << 8)) << 9; P_printf("data image length: 0x%x, ind: 0x%x\n", image_length,indicator); ptr = ptr + image_length; continue; } /* OK, we have a PC Image */ length = (*(ptr + 2) << 9); P_printf("BIOS length: 0x%x\n",length); scratch = (unsigned char *)malloc(length); /* don't use memcpy() here: Reading from bus! */ for (i=0;i<length;i++) *(scratch + i)=*(ptr + i); break; } /* unmap/close/disable PCI bios mem */ munmap(mem, biosSize); close(mem_fd); /* disable and restore mapping */ writePci(CurrentPci->Slot.l | 0x30, CurrentPci->RomBase & ~(CARD32)1); if (scratch && length) { memcpy((unsigned char *)V_BIOS, scratch, length); free(scratch); } restoreMem(); return length;}CARD32findPci(CARD16 slotBX){ CARD32 slot = slotBX << 8; if (slot == (CurrentPci->Slot.l & ~PCI_EN)) return (CurrentPci->Slot.l | PCI_EN); else { PciBusPtr pBus = CurrentPci->pBus; while (pBus) { printf("slot: 0x%x bridge: 0x%x\n",slot, pBus->Slot.l); if (slot == (pBus->Slot.l & ~PCI_EN)) return pBus->Slot.l | PCI_EN; pBus = pBus->next; } } return 0;}CARD16pciSlotBX(void){ return (CARD16)((CurrentPci->Slot.l >> 8) & 0xFFFF);}static voidreadConfigSpaceCfg1(CARD32 bus, CARD32 dev, CARD32 func, CARD32 *reg){ CARD32 config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); int i; for (i = 0; i<64;i+=4) {#ifdef __alpha__ reg[i] = axpPciCfgRead(config_cmd | i);#else outl(PCI_MODE1_ADDRESS_REG, config_cmd | i); reg[i] = inl(PCI_MODE1_DATA_REG);#endif#ifdef DEBUG P_printf("0x%lx\n",reg[i]);#endif }}static intcheckSlotCfg1(CARD32 bus, CARD32 dev, CARD32 func){ CARD32 config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); CARD32 reg;#ifdef __alpha__ reg = axpPciCfgRead(config_cmd);#else outl(PCI_MODE1_ADDRESS_REG, config_cmd); reg = inl(PCI_MODE1_DATA_REG);#endif if (reg != 0xFFFFFFFF) return 1; else return 0;}static intcheckSlotCfg2(CARD32 bus, int dev){ CARD32 val; outb(PCI_MODE2_ENABLE_REG, 0xF1); outb(PCI_MODE2_FORWARD_REG, bus); val = inl(dev << 8); outb(PCI_MODE2_FORWARD_REG, 0x00); outb(PCI_MODE2_ENABLE_REG, 0x00); if (val == 0xFFFFFFFF) return 0; if (val == 0xF0F0F0F0) return 0; return 1;}static voidreadConfigSpaceCfg2(CARD32 bus, int dev, CARD32 *reg){ int i; outb(PCI_MODE2_ENABLE_REG, 0xF1); outb(PCI_MODE2_FORWARD_REG, bus); for (i = 0; i<64;i+=4) { reg[i] = inl((dev << 8) + i);#ifdef DEBUG P_printf("0x%lx\n",reg[i]);#endif } outb(PCI_MODE2_ENABLE_REG, 0x00);}static CARD8interpretConfigSpace(CARD32 *reg,CARD32 *pcibuses, int busidx, CARD8 dev, CARD8 func){ CARD32 config_cmd; CARD16 vendor, device; CARD8 baseclass, subclass; CARD8 primary, secondary; CARD8 header, interface; int i; config_cmd = PCI_EN | (pcibuses[busidx]<<16) | (dev<<11) | (func<<8); for (i = 0x10; i < 0x28; i+=4) { if (IS_MEM32(reg[i])) if ((reg[i] & 0xFFFFFFF0) < pciMinMemReg) pciMinMemReg = (reg[i] & 0xFFFFFFF0);#ifdef __alpha__ if (IS_MEM64(reg[i])) { unsigned long addr = reg[i] | (unsigned long)(reg[i+4]) << 32; if ((addr & ~0xfL) < pciMinMemReg) pciMinMemReg = (addr & ~0xfL); i+=4; }#endif } vendor = reg[0] & 0xFFFF; device = reg[0] >> 16; P_printf("bus: %i card: %i func %i reg0: 0x%x ", pcibuses[busidx],dev,func,reg[0]); baseclass = reg[8] >> 24; subclass = (reg[8] >> 16) & 0xFF; interface = (reg[8] >> 8) & 0xFF; header = (reg[0x0c] >> 16) & 0xff; P_printf("bc 0x%x, sub 0x%x, if 0x%x, hdr 0x%x\n", baseclass,subclass,interface,header); if (BRIDGE_CLASS(baseclass)) { if (BRIDGE_PCI_CLASS(subclass)) { PciBusPtr pbp = malloc(sizeof(PciBusRec)); P_printf("Pci-Pci Bridge found; "); primary = reg[0x18] & 0xFF; secondary = (reg[0x18] >> 8) & 0xFF; P_printf("primary: 0x%x secondary: 0x%x\n", primary,secondary); pbp->bctl = reg[0x3c]; pbp->primary = primary; pbp->secondary = secondary; pbp->Slot.l = config_cmd; pbp->next = PciBuses; PciBuses = pbp; if (secondary >= 1) pcibuses[numbus++] = secondary; } else if (BRIDGE_HOST_CLASS(subclass) && (hostbridges++ > 1)) { pcibuses[numbus] = numbus; numbus++; } } else if (VIDEO_CLASS(baseclass,subclass)) { PciStructPtr pcp = malloc(sizeof(PciStructRec)); P_printf("Display found\n"); pcp->RomBase = reg[0x30]; pcp->cmd_st = reg[4]; pcp->active = (reg[4] & 0x03) == 3 ? 1 : 0; pcp->VendorID = vendor; pcp->DeviceID = device; pcp->Interface = interface; pcp->BaseClass = baseclass; pcp->SubClass = subclass; pcp->Slot.l = config_cmd; pcp->bus = pcibuses[busidx]; pcp->dev = dev; pcp->func = func; pcp->next = PciStruct; PciStruct = pcp; } if ((func == 0) && ((header & PCI_MULTIFUNC_DEV) == 0)) func = 8; else func++; return func;}static CARD32 remapMEM_val;static int remapMEM_num;static int /* map it on some other video device */remapMem(int num, CARD32 size){ PciStructPtr pciPtr = PciStruct; int i; CARD32 org; CARD32 val; CARD32 size_n; org = PciRead32(num + 0x10,CurrentPci->Slot.l); while (pciPtr) { for (i = 0; i < 20; i=i+4) { val = PciRead32(i + 0x10,pciPtr->Slot.l); /* don't map it on itself */ if ((org & 0xfffffff0) == (val & 0xfffffff0)) continue; if (val && !(val & 1)) PciWrite32(i + 0x10,0xffffffff,pciPtr->Slot.l); else continue; size_n = PciRead32(i + 0x10,pciPtr->Slot.l); PciWrite32(i + 0x10,val,pciPtr->Slot.l); size_n = ~(CARD32)(size_n & 0xfffffff0) + 1; if (size_n >= size) { PciWrite32(num + 0x10,val,CurrentPci->Slot.l); return 1; } } pciPtr = pciPtr->next; } /* last resort: try to go below lowest PCI mem address */ val = ((pciMinMemReg & ~(CARD32)(size - 1)) - size); if (val > 0x7fffffff) { PciWrite32(num + 0x10,val, CurrentPci->Slot.l); return 1; } return 0;}static voidrestoreMem(void){ if (remapMEM_val == 0) return; PciWrite32(remapMEM_num + 0x10,remapMEM_val,CurrentPci->Slot.l); return;}static CARD32findBIOSMap(CARD32 *biosSize){ PciStructPtr pciPtr = PciStruct; int i; CARD32 val; CARD32 size; PciWrite32(0x30,0xffffffff,CurrentPci->Slot.l); *biosSize = PciRead32(0x30,CurrentPci->Slot.l); P_printf("bios size: 0x%x\n",*biosSize); PciWrite32(0x30,CurrentPci->RomBase,CurrentPci->Slot.l); *biosSize = ~(*biosSize & 0xFFFFFF00) + 1; P_printf("biosSize: 0x%x\n",*biosSize); if (*biosSize > (1024 * 1024 * 16)) { *biosSize = 1024 * 1024 * 16; P_printf("fixing broken BIOS size: 0x%x\n",*biosSize); } while (pciPtr) { if (pciPtr->bus != CurrentPci->bus) { pciPtr = pciPtr->next; continue; } for (i = 0; i < 20; i=i+4) { val = PciRead32(i + 0x10,pciPtr->Slot.l); if (!(val & 1)) PciWrite32(i + 0x10,0xffffffff,pciPtr->Slot.l); else continue; size = PciRead32(i + 0x10,pciPtr->Slot.l); PciWrite32(i + 0x10,val,pciPtr->Slot.l); size = ~(CARD32)(size & 0xFFFFFFF0) + 1; P_printf("size: 0x%x\n",size); if (size >= *biosSize) { if (CurrentPci == pciPtr) { /* if same device remap ram*/ if (!(remapMem(i,size))) continue; remapMEM_val = val; remapMEM_num = i; } else { remapMEM_val = 0; } return val & 0xFFFFFF00; } } pciPtr = pciPtr->next; } remapMEM_val = 0; /* very last resort */ if (CurrentPci->bus == 0 && (pciMinMemReg > *biosSize)) return (pciMinMemReg - size) & ~(size - 1); return 0;}intcfg1out(CARD16 addr, CARD32 val){ if (addr == 0xCF8) { PciCfg1Addr = val; return 1; } else if (addr == 0xCFC) { writePci(PciCfg1Addr, val); return 1; } return 0;}int cfg1in(CARD16 addr, CARD32 *val){ if (addr == 0xCF8) { *val = PciCfg1Addr; return 1; } else if (addr == 0xCFC) { *val = readPci(PciCfg1Addr); return 1; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -