📄 rinit.c
字号:
void main(int argc, char** argv)
{
int i,j;
unsigned short command=0; //value of command is a set of corresponding bits of command line parameters
char* filename; //points to name of file directly in argv buffer
unsigned long header_4bytes; //variable to read first 4 bytes of file to determine binary size and validate signature
long binary_size; //size of BIOS binary
int handle; //file handle
char text_buffer[80];//buffer to store char lines used for graphics output
int ret;
unsigned long c0000003 = 0xc0000003;
int devnum;
char* source;
unsigned long bar,viph,eprom_cntl,temp;
if (check_for_v86()) // Exits if not pure DOS
{
printf("\nThis program cannot be run in a virtual 86 mode!");
return;
}
buffer = NULL; ret=0;
if (argc <= 1)
{
// If program was run with no parameters USAGE help is displayed .
usage();
} else
{
for (i=1; i < argc; i++)
{
for (j=0;j<CMD_NUMBER;j++)
if (memicmp(argv[i],commands[j].cmd_str,strlen(commands[j].cmd_str)) == 0)
{
// If input parameter is equal to cmd_str from "commands" structure, we assign corresponding bit to current command
command|=commands[j].index;
if (commands[j].index==cmdFILE)
{
// If it's binary file name input, the name of file must be placed right after "FILE="
if ((filename=strchr(argv[i],'=')) != NULL)
{
filename++;
} else
{
// Program exits when name of file is not placed properly
// The alternative of file is a current video BIOS binary, put BIOS command to use it.
printf("\nEnter name of file using format [file=name of file]..");
return;
}
}
}
}
if (!command) // if there were no recognized commands - print help
{
usage(); return;
}
if (command & cmdINIT) command &= ~cmdINFO; // if both INIT & INFO - exclude INFO
if ((command & (cmdBIOS+cmdFILE)) == 0)
{
// If you have forgotten to choose one of the options BIOS or FILE program exits
printf("\nTables source is not given, use FILE or BIOS commands");
return;
}
if ((command & (cmdINIT+cmdINFO)) == 0)
{
// If you have forgotten to choose one of the options INIT or INFO program exits
printf("\nUse commands INIT or INFO to run the initialization sequence.");
return;
}
// Getting all the cards plugged to PCI or AGP
if (!(devnum=get_pci_location()))
{
printf("\nNo ATI card is found!");
return;
}
// If more then one card program displays all existed and you can choose one of them
// Using cprintf instead of printf gives you an opportunity to keep that menu on a
// screen even if you redirect output to file.
if (devnum > 1)
{
sprintf(text_buffer,"More than one ATI adapter found... ");
scprintf(text_buffer,strlen(text_buffer),0);
sprintf(text_buffer,"N. Bus Dev ID Status ");
scprintf(text_buffer,strlen(text_buffer),1);
for (i=0;i<devnum;i++)
{
sprintf(text_buffer,"%d. %02x %02x %04x %s",i,
device[i].busdevfnc >> 8,
(device[i].busdevfnc >> 3) & 0x1F,
device[i].ID,
status_str[((device[i].config & MEM_IO_ENABLE)==MEM_IO_ENABLE) ? 0 : 1]);
scprintf(text_buffer,strlen(text_buffer),i+2);
}
sprintf(text_buffer,"Choose a card to initialize: ");
scprintf(text_buffer,strlen(text_buffer),i+2);
scanf("%d",&i); // getting index of a card from users input
defaultdev=device+i; // assigning default device
// if the device is not primary by default, we set IO and Memory Acces bits as well as bus mastering
if ((defaultdev->config & MEM_IO_ENABLE)==0)
{
pci_outword(defaultdev->busdevfnc, PCI_CONFIG, pci_inword(defaultdev->busdevfnc, PCI_CONFIG) | MEM_IO_ENABLE);
}
}
if (command & cmdBIOS)
{
// If it's BIOS command we read BIOS binary from expansion ROM
viph=InpIndexRegs(VIPH_CONTROL);
OutIndexRegs(VIPH_CONTROL,viph & ~VIPH_ENABLE); // Seting up the ROM access
bar=pci_indword(defaultdev->busdevfnc, PCI_BAR); // Reading BAR (Expansion ROM address)
eprom_cntl=InpIndexRegs(SEPROM_CONTROL1);
// Slow down EEPROM access clock
OutIndexRegs(SEPROM_CONTROL1,(eprom_cntl & 0x00ffffff) | 0x06000000);
if (bar == 0) // If BAR was not initialized by BIOS
{
// Assign a0000 and make it active (0xa0001)
source=(char*)0xa0000000; // just pointer to a0000
pci_outdword(defaultdev->busdevfnc, PCI_BAR, 0xa0001);
//if not valid ROM, but it's primary card - getting binary from c0000
if ((*(unsigned short*)source != 0xAA55) && ((defaultdev->config & MEM_IO_ENABLE)!=0)) source=(char*)0xc0000000;
if (*(unsigned short*)source == 0xAA55)
{
// if valid ROM : getting binary size
binary_size=(unsigned short)source[3]*BLOCK_SIZE;
// allocating memory buffer
buffer = malloc((unsigned short)binary_size);
if (buffer==NULL)
{
ret=1;
perror("Memory allocation error!");
}
// copying data from found source
memcpy(buffer, source, binary_size);
} else
{
printf("\nCannot read tables from adapter!");
ret=1;
}
} else
{
// if BAR is not zero, it should me upstairs
bar&=0xfffffff0;
// anyway making it active
pci_outdword(defaultdev->busdevfnc, PCI_BAR, bar | 1);
// reading first 4 bytes usign protected mode access
delay_ns(10000);
temp=readxmsdword(bar);
// if binary is valid
if ((unsigned short)temp == 0xAA55)
{
// getting binary size
binary_size=((unsigned short) ((temp >> 16)& 0xff))*BLOCK_SIZE;
// allocating memory buffer of that size
buffer = malloc((unsigned short)binary_size);
if (buffer==NULL)
{
perror("Memory allocation error!");
ret=1;
} else
{
// and reading data from ROM to the buffer printf("1\n");
readxmsbuffer(buffer,bar, binary_size);
// readxmsdword and readxmsbuffer use BIG DOS mode
// it's not necessary to load any memory menagers (himem or so)
}
} else
{
printf("\nCannot read tables from adapter!");
ret=1;
}
}
//restore VIP Host and EPROM control registers
OutIndexRegs(VIPH_CONTROL,viph);
OutIndexRegs(SEPROM_CONTROL1,eprom_cntl);
//restore BAR register
pci_outdword(defaultdev->busdevfnc, PCI_BAR, bar);
//if one of the recent operations failed
if (ret)
{
postprocess(); //do some work before leaving the program
return; //exit
}
// }
} else
if (command & cmdFILE)
{
// If we are still here and have chosen FILE options opening the file
if ((handle=_open(filename,O_RDONLY+O_BINARY)) == -1)
{
perror("Cannot find BIOS binary file!");
postprocess();
return;
}
// Reading of first 4 bytes
if (_read(handle,&header_4bytes,4) == -1)
{
perror("Cannot read BIOS binary file!");
close(handle);
postprocess();
return;
}
//Checking if it is video BIOS binary
if ((unsigned short)header_4bytes != 0xAA55)
{
perror("Invalid BIOS binary format!");
close(handle);
postprocess();
return;
}
//Getting the size of bunary multiplying 3rd byte of binary by 512 bytes
binary_size=((unsigned short) ((header_4bytes >> 16)& 0xff))*BLOCK_SIZE;
//Binary cannot be bigger than one segment
if (binary_size > 0xFFFF)
{
perror("BIOS binary file bigger than 64k!");
close(handle);
postprocess();
return;
}
//Allocation of memory for data from video BIOS binary file
buffer = malloc((unsigned short)binary_size);
if (buffer==NULL)
{
perror("Memory allocation error!");
close(handle);
postprocess();
return;
}
//Reading the binary into the buffer
lseek(handle, 0L, SEEK_SET);
if (_read(handle,buffer,(unsigned short)binary_size) == -1)
{
perror("Cannot read BIOS binary file!");
close(handle);
postprocess();
return;
}
// We are done with the file
close(handle);
}
// Here we are getting and validating pointers to init tables
rom_hdr_rev_pointer = buffer+*(unsigned short*)(buffer+OFF_ROM_HEAD); // ROM Header revision pointer
// going through tables_info structure
for (i=0;i<INIT_TABLES_NUMBER;i++)
{
if (tables[i].pointer) // if we have destination pointer
{
if (tables[i].offset !=0) // if we have offset of table
{
// assigning address to destination pointer
temp=*(unsigned short*)(buffer+*(unsigned short*)(buffer+OFF_ROM_HEAD)+tables[i].offset);
if (temp) *tables[i].pointer=buffer+*(unsigned short*)(buffer+*(unsigned short*)(buffer+OFF_ROM_HEAD)+tables[i].offset);
} else
{
// if we don't have an offset we are looking for table relaying on other table pointer
*tables[i].pointer = tables[i].look_for(tables[i].parent_table);
}
// if we have validation function - checking if pointer is valid
if (tables[i].validate) tables[i].validate(&tables[i]);
}
// if (rev >= 9) getting only first table
if (*rom_hdr_rev_pointer >= SINGLE_TABLE_REVISION) break;
}
// This condition means that if found pointer of ASIC init table 3 is the same as
// pointer on PLL init table - we do not have ASIC init tables 3 and 4
if (rage_regs_3_table+1 == pll_init_table)
{
rage_regs_3_table=rage_regs_4_table=NULL;
}
if ((command & cmdINIT) || (command & cmdINFO))
{
// starting initialization sequence
// running ASIC init table #1 in any case
// it can be first table of sequence or the only table if BIOS revision = 9
if (rage_regs_1_table !=NULL) ret = LoadInitBlock(rage_regs_1_table,command, "ASIC INIT TABLE #1");
if (*rom_hdr_rev_pointer < SINGLE_TABLE_REVISION)
{
// continue if older BIOS
if (pll_init_table !=NULL) ret &= LoadPLLBlock(pll_init_table,command,"PLL INIT TABLE");
if (rage_regs_2_table !=NULL) ret &= LoadInitBlock(rage_regs_2_table,command,"ASIC INIT TABLE #2");
if (rage_regs_4_table != NULL) ret &= LoadInitBlock(rage_regs_4_table,command,"ASIC INIT TABLE #4");
if (mem_reset_table != NULL) ret &= Reset_SDRAM(mem_reset_table,command,"MEMORY RESET TABLE");
if (rag
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -