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

📄 pci.c

📁 BIOS emulator and interface to Realmode X86 Emulator Library Can emulate a PCI Graphic Controller V
💻 C
📖 第 1 页 / 共 2 页
字号:
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 + -