/********************************************************/ /* PCIHOST.C Host Platform dependant functions. */ /* This version for PCI machines. */ /********************************************************/ /* Required for inline code to run through TASM to access 386 */ /* registers used by PCI BIOS 2.0+ */ #pragma asm -warn #pragma inline #define MAX_PCI_DEVICES 10 #define FORCE_IO_ADDR 0x4000 void SetConfigRegister(); #include "pci.h" #include #include /* External variables */ extern unsigned char (*GetRegister)(int); extern void (*SetRegister)(int, unsigned char); extern unsigned char* siop_registers; extern unsigned int base_address; /* Local variables */ struct device_record { unsigned int bus_num; unsigned int slot_num; unsigned int device_id; unsigned int device_index; }; static unsigned int bus_num=0,slot_num=0; static struct REGPACK regs; static unsigned int pci_ver=0; static struct device_record Devices[MAX_PCI_DEVICES]; static unsigned int num_devices=0; /* Local variables for registers for INT calls */ static unsigned r_ax; static unsigned r_bx; static unsigned r_cx; static unsigned long r_ecx; static unsigned r_dx; static unsigned long r_edx; static unsigned r_di; /* Global variables */ int dev_index=0; /* Function prototypes */ unsigned char GetMemoryRegister(); unsigned long GetIOBase(); void SetMemoryRegister(); unsigned char GetIORegister(); void SetIORegister(); unsigned int GetPCIBIOSVersion(); unsigned long GetMemoryBase(); unsigned long GetConfigRegister(); void SetAddress(); /********************************************************/ char *DevID2Str(id) int id; { switch (id) { case C810_DEVICE_ID: return("NCR 53C810"); case C820_DEVICE_ID: return("NCR 53C820"); case C825_DEVICE_ID: return("NCR 53C825"); case C815_DEVICE_ID: return("NCR 53C815"); default: return("Unknown"); } } /********************************************************/ struct device_record *FindNCRDevice(devid,index,devnum) unsigned int devid; int index,devnum; { regs.r_ax = ((PCI_FUNCTION_ID << 8) | (FIND_PCI_DEVICE)); regs.r_cx = devid; regs.r_dx = NCR_VENDOR_ID; regs.r_si = index; intr(PCI_BIOS_INT,®s); if (regs.r_flags & 0x01) { /* No such device found */ return(NULL); } Devices[devnum].bus_num = (regs.r_bx & 0x00ff); /* BL = bus num */ Devices[devnum].slot_num = ((regs.r_bx & 0xff00) >> 8); /* BH = slot num */ Devices[devnum].device_id = devid; /* Device ID */ Devices[devnum].device_index = index; /* Device Index */ return(1); } /********************************************************/ int ChooseDevice() { int devnum=0,index=0; /* Scan system for 53C810s */ index=0; while (FindNCRDevice(C810_DEVICE_ID,index,devnum) != NULL) { devnum++; index++; } /* Scan system for 53C820s */ index=0; while (FindNCRDevice(C820_DEVICE_ID,index,devnum) != NULL) { devnum++; index++; } /* Scan system for 53C825s */ index=0; while (FindNCRDevice(C825_DEVICE_ID,index,devnum) != NULL) { devnum++; index++; } /* Scan system for 53C815s */ index=0; while (FindNCRDevice(C815_DEVICE_ID,index,devnum) != NULL) { devnum++; index++; } num_devices = devnum; if (dev_index == 0) { /* No choice specified on command line */ printf("The following parts were located:\n"); for (index = 0; index < num_devices; index++) { printf("%d\t%s DeviceIndex %x\tIO ADDR=%04x\n",index,DevID2Str(Devices[index].device_id),Devices[index].device_index,GetIOBase(index)); } printf("\rChoose a part: "); scanf("%d",&dev_index); while ((dev_index < 0) || (dev_index >= num_devices)) { printf("\007\rChoose a part: "); scanf("%d",&dev_index); } //clrscr(); } /* Assign slot/bus num to selected device's info */ slot_num=Devices[dev_index].slot_num; bus_num=Devices[dev_index].bus_num; return dev_index; } /********************************************************/ void HostDependentInit() { unsigned long cmd_reg=0; unsigned long mem_addr=0; int devnum; extern unsigned int MEM_MAP; extern unsigned int C7XX_SEG; unsigned long devvendid_reg; /* Ensure existence of PCI BIOS extensions */ pci_ver = GetPCIBIOSVersion(); if (pci_ver == 0x00) /* No PCI BIOS found..continue anyway */ { printf("\nHit any key to continue\n"); getch(); return; }; printf("BIOS Version = %02x\n",pci_ver); /* Ensure existence of 53C8XX */ devnum=ChooseDevice(); cmd_reg = GetConfigRegister(0x04); /* Read COMMAND reg */ if (cmd_reg & 0x01) { /* I/O space enabled? */ MEM_MAP=0; SetAddress(devnum); } else if (cmd_reg & 0x02) { /* Memory space enabled? */ MEM_MAP=1; /* Read absolute memory address - NOT SEG:OFF ! */ r_ax = ((PCI_FUNCTION_ID << 8) | (READ_CONFIG_DWORD)); r_bx = ((slot_num & 0xff) << 8) | (bus_num & 0xff); r_di = MEM_BASE_REG; asm { .386 mov ax,[r_ax] mov bx,[r_bx] mov di,[r_di] int PCI_BIOS_INT mov [r_dx],dx mov [r_cx],cx mov DWORD PTR [r_ecx],ecx } if (pci_ver < 0x200) { /* Version 1.x */ mem_addr = r_dx; mem_addr = (mem_addr << 16) | r_cx; } else { /* Version 2.x */ mem_addr = r_ecx; } if (mem_addr < 0x100000) { MEM_MAP=1; } else { MEM_MAP=0; } } else { /* NEITHER?!?!?!? */ fprintf(stderr,"\n\n\n***** WARNING: BIOS DID NOT MAP %s as either I/O or MEMORY!!! *****\n\n\n",DevID2Str(Devices[dev_index].device_id)); fprintf(stderr,"Mapping device at I/O %04x ... \n\n\n",FORCE_IO_ADDR); /* I/O Map chip at FORCE_IO_ADDR */ MEM_MAP=0; SetConfigRegister(IO_BASE_REG,(unsigned long)FORCE_IO_ADDR); /* Enable I/O access to 8xx */ SetConfigRegister(0x04,(cmd_reg | 0x145)); SetAddress(devnum); printf("Hit any key/n"); getch(); } } /********************************************************/ void SetConfigRegister(int number, unsigned long value) { r_ax = ((PCI_FUNCTION_ID << 8) | (WRITE_CONFIG_DWORD)); r_bx = ((slot_num & 0xff) << 8) | (bus_num & 0xff); r_di = number; if (pci_ver < 0x200) { /* Version 1.x */ r_dx = (value >> 16); r_cx = (value & 0xffff); } else { /* Version 2.x */ r_ecx = value; } asm { .386 mov ax,[r_ax] mov bx,[r_bx] mov cx,[r_cx] mov dx,[r_dx] mov ecx,DWORD PTR [r_ecx] mov di,[r_di] int PCI_BIOS_INT } } /**************************************************************** Read a longword from a Configuration Register ****************************************************************/ unsigned long GetConfigRegister(int number) { unsigned long result=0; r_ax = ((PCI_FUNCTION_ID << 8) | (READ_CONFIG_DWORD)); r_bx = ((slot_num & 0xff) << 8) | (bus_num & 0xff); r_di = number; asm { .386 mov ax,[r_ax] mov bx,[r_bx] mov di,[r_di] int PCI_BIOS_INT mov [r_dx],dx mov [r_cx],cx mov DWORD PTR [r_ecx],ecx } if (pci_ver < 0x200) { /* Version 1.x */ result = r_dx; result = (result << 16) | r_cx; } else { /* Version 2.x */ result = r_ecx; } return(result); } /********************************************************/ unsigned long GetMemoryBase() { unsigned long temp=0,result=0; extern unsigned int seg,off; r_ax = ((PCI_FUNCTION_ID << 8) | (READ_CONFIG_DWORD)); r_bx = ((slot_num & 0xff) << 8) | (bus_num & 0xff); r_di = MEM_BASE_REG; asm { .386 mov ax,[r_ax] mov bx,[r_bx] mov di,[r_di] int PCI_BIOS_INT mov [r_dx],dx mov [r_cx],cx mov DWORD PTR [r_ecx],ecx } if (pci_ver < 0x200) { /* Version 1.x */ temp = r_dx; temp = (temp << 16) | r_cx; } else { /* Version 2.x */ temp = r_ecx; } seg = (temp >> 4); off = (temp - (seg << 4)); result = seg; result = (result << 16) | off; return(result); } unsigned long GetIOBase(int dev_num) { unsigned long temp=0; r_ax = ((PCI_FUNCTION_ID << 8) | (READ_CONFIG_DWORD)); r_bx = ((Devices[dev_num].slot_num & 0xff) << 8) | (Devices[dev_num].bus_num & 0xff); r_di = IO_BASE_REG; asm { .386 mov ax,[r_ax] mov bx,[r_bx] mov di,[r_di] int PCI_BIOS_INT mov [r_dx],dx mov [r_cx],cx mov DWORD PTR [r_ecx],ecx } if (pci_ver < 0x200) { /* Version 1.x */ temp = r_dx; temp = (temp << 16) | (r_cx & 0xfffe); /* Strip I/O indicator bit */ } else { /* Version 2.x */ temp = (r_ecx & 0xfffffffe); /* Strip I/O indicator bit */ } return(temp); } unsigned int GetPCIBIOSVersion() { unsigned long sig=0; asm { .386 mov ax,((PCI_FUNCTION_ID SHL 8) OR (PCI_BIOS_PRESENT)) int PCI_BIOS_INT mov DWORD PTR [r_edx],edx mov [r_dx],dx mov [r_cx],cx mov [r_bx],bx } sig = ('I' | (' ' << 8)); sig = ((sig << 16) | ('P' | ('C' << 8))); /* sig = (unsigned long)('P' | ('C' << 8) | ('I' << 16) | (' ' << 24)); */ if (r_dx == (('P') | ('C' << 8))) { if (((r_cx & 0xff) == 'I') && ((r_bx & 0xff00) == 0x0100)) { /* Rev 1.x BIOS */ return(0x0100); } else if (r_edx == sig) { /* Rev 2.x BIOS */ return(0x0200); } else { fprintf(stderr,"\n\n\n***** NO KNOWN PCI BIOS Found!!!! *****\n\n\n"); return(0x00); } } else { fprintf(stderr,"\n\n\n***** NO PCI BIOS Found!!!! *****\n\n\n"); return(0x00); } } /********************************************************/ /* Setup base address of chip for program */ void SetAddress(int devnum) { extern unsigned int C7XX_SEG; extern unsigned int MEM_MAP; switch (MEM_MAP) { case 0: C7XX_SEG = GetIOBase(devnum); // GetRegister = GetIORegister; // SetRegister = SetIORegister; break; case 1: C7XX_SEG = GetMemoryBase(); // GetRegister = GetMemoryRegister; // SetRegister = SetMemoryRegister; break; } } void SetAddressMode(int mode) { extern unsigned int MEM_MAP; extern unsigned int C7XX_SEG; // if (mode != GetVariableValue(VARIABLE_MEMORY)) switch (MEM_MAP) { case 0: C7XX_SEG = GetIOBase(0); //GetRegister = GetIORegister; //SetRegister = SetIORegister; break; case 1: C7XX_SEG = GetMemoryBase(); //GetRegister = GetMemoryRegister; //SetRegister = SetMemoryRegister; break; } }