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

📄 s3elsa.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
字号:
/* $XFree86: xc/programs/Xserver/hw/xfree86/accel/s3/s3ELSA.c,v 3.20.2.1 1997/05/06 13:25:40 dawes Exp $ *//*  * s3ELSA.c  *  * compile standalone program with    *      rm -f s3ELSA.o      make DEFINES=-DELSA_MAIN "LDLIBS=../../os-support/libxf86_os.a" s3ELSA       rm -f s3ELSA.o *  *  *//* $XConsortium: s3ELSA.c /main/10 1996/10/28 04:55:10 kaleb $ */#ifdef linux#include <stdlib.h>#endif#include "s3.h"#include "s3ELSA.h"#include "xf86_OSlib.h"#ifdef ELSA_MAIN#include <stdio.h>#ifdef linux#include <unistd.h>#endif /* linux */#ifndef SVR4#include <getopt.h>#endif /* SVR4 */#ifdef xalloc#undef xalloc#endif#define xalloc(_p) malloc(_p)#ifdef xrealloc#undef xrealloc#endif#define xrealloc(_o,_s) realloc(_o,_s)#ifdef xfree#undef xfree#endif#define xfree(_p) free(_p)#endif /* ELSA_MAIN */#define BIOS_BSIZE 512#define BIOS_BASE  0xc0000elsa_board_types_t elsa_board_types[] = {   { ELSA_WINNER_1000,		"ELSA Winner 1000",		0 },   { ELSA_WINNER_1000VL,	"ELSA Winner 1000VL",		0 },   { ELSA_WINNER_1000PCI,	"ELSA Winner 1000PCI",		0 },   { ELSA_WINNER_1000ISA,	"ELSA Winner 1000ISA",		0 },   { ELSA_WINNER_2000,		"ELSA Winner 2000",		0 },   { ELSA_WINNER_2000VL,	"ELSA Winner 2000VL",		0 },   { ELSA_WINNER_2000PCI,	"ELSA Winner 2000PCI",		0 },   { ELSA_WINNER_1000PRO,	"ELSA Winner 1000PRO",		0 },   { ELSA_WINNER_1000PRO_TRIO32,"ELSA Winner 1000PRO Trio32",	0 },   { ELSA_WINNER_1000PRO_TRIO64,"ELSA Winner 1000PRO Trio64",	0 },   { ELSA_WINNER_1000AVI,	"ELSA Winner 1000AVI",		0 },   { ELSA_WINNER_1000PRO_X,	"ELSA Winner 1000PRO/X",	0 },   { ELSA_WINNER_2000PRO,	"ELSA Winner 2000PRO",		0 },   { ELSA_WINNER_2000PRO_X,	"ELSA Winner 2000PRO/X",	0 },   { ELSA_WINNER_2000AVI,	"ELSA Winner 2000AVI",		0 },   { ELSA_WINNER_2000PRO_X8,	"ELSA Winner 2000PRO/X-8",	0 },   { ELSA_GLORIA_4,		"ELSA Gloria-4",		0 },   { ELSA_GLORIA_8,		"ELSA Gloria-8",		0 },   { 0, 0, 0 }};static __inline__ void shift_out(int b) {   int i,j;    outb(0x3d4,0x5c); i = (inb(0x3d5) & 0xaf) | ((b)?0x10:0x00);    j = i;     outb(0x3d5,j); outb(0x3d5,j); outb(0x3d5,j); outb(0x3d5,j);    j = i | 0x40;     outb(0x3d5,j); outb(0x3d5,j); outb(0x3d5,j); outb(0x3d5,j); } static __inline__ int shift_in(){    int i,j;    outb(0x3d4,0x5c); i = inb(0x3d5) & 0xaf;    j = i;     outb(0x3d5,j); outb(0x3d5,j); outb(0x3d5,j); outb(0x3d5,j);    j = i | 0x40;     outb(0x3d5,j); outb(0x3d5,j); outb(0x3d5,j); outb(0x3d5,j);    return (inb(0x3c2) & 0x10) != 0;} static int read_eeprom_byte(int r){   int i,j;      outb(0x3d4,0x5c); i = inb(0x3d5) |  0x20; outb(0x3d5,i);   outb(0x3d5,i); outb(0x3d5,i); outb(0x3d5,i);   shift_out(1);   shift_out(1);   shift_out(0);      for(i=5; i>=0; i--)      shift_out((r>>i) & 1);   #if 0   shift_out(0);#endif   j=0;   for(i=0; i<16; i++)       j = (j<<1) | shift_in();   outb(0x3d4,0x5c); i = inb(0x3d5) & ~0x20; outb(0x3d5,i);   outb(0x3d5,i); outb(0x3d5,i); outb(0x3d5,i);   return j;}static int read_eeprom_data(unsigned short **pdata){   int i;   int sr01, cr45, cr50, cr55, cr5c;   int ndata=6;   unsigned short *data;   elsa_eeprom_data_t *eedata;#ifdef ELSA_MAIN#ifdef linux   iopl(3);#endif#endif   outb(0x3d4,0x38); outb(0x3d5,0x48);   outb(0x3d4,0x39); outb(0x3d5,0xa5);   outb(0x3c4,0x01); sr01 = inb(0x3c5);   outb(0x3d4,0x45); cr45 = inb(0x3d5);   outb(0x3d4,0x50); cr50 = inb(0x3d5);   outb(0x3d4,0x55); cr55 = inb(0x3d5);   outb(0x3d4,0x5c); cr5c = inb(0x3d5);   outb(0x3c4,0x01); i = inb(0x3c5) |  0x20; outb(0x3c5,i);   outb(0x3d4,0x45); i = inb(0x3d5) & ~0x20; outb(0x3d5,i);   outb(0x3d4,0x50); i = inb(0x3d5) & ~0x04; outb(0x3d5,i);   outb(0x3d4,0x55); i = inb(0x3d5) & ~0x20; outb(0x3d5,i);   outb(0x3d4,0x5c); i = inb(0x3d5) |  0x80; outb(0x3d5,i);   outb(0x3d5,i); outb(0x3d5,i); outb(0x3d5,i);   for(i=0; i<64; i++)      shift_out(0);   data = (unsigned short*) xalloc(ndata*sizeof(unsigned short));   for (i=0; i<ndata; i++)      data[i] = read_eeprom_byte(i);   eedata = (elsa_eeprom_data_t *) data;   if (eedata->wnr_type == ('S' | '3'<<8)) {      if (eedata->eeprom_size > ndata) {	 ndata = eedata->eeprom_size;	 data = (unsigned short*) xrealloc(data, ndata*sizeof(unsigned short));	 for (; i<ndata; i++)	    data[i] = read_eeprom_byte(i);      }   }   outb(0x3d4,0x5c); outb(0x3d5,cr5c);   outb(0x3d4,0x55); outb(0x3d5,cr55);   outb(0x3d4,0x50); outb(0x3d5,cr50);   outb(0x3d4,0x45); outb(0x3d5,cr45);   outb(0x3c4,0x01); outb(0x3c5,sr01);#if 0   outb(0x3d4,0x39); outb(0x3d5,0x00);   outb(0x3d4,0x38); outb(0x3d5,0x00);#endif#ifdef ELSA_MAIN#ifdef linux   iopl(0);#endif#endif   eedata = (elsa_eeprom_data_t *) data;   if (eedata->wnr_type == ('S' | '3'<<8)) {      *pdata = data;   }   else {      xfree(data);      ndata = -1;   }   return ndata;}static int calc_crc16(int ndata, unsigned short *data){   int i,j,s,crc16;   unsigned short d;      crc16 = 0;   for(i=1; i<ndata; i++) {      d = data[i];      for (j=0; j<16; j++) {	 s = (crc16>>1) + (crc16>>14) + (crc16>>15) + d + 1;	 crc16 = (crc16<<1) | (s&1);	 d >>= 1;      }   }   return crc16;}static int check_ELSA_bios(int BIOSbase){   unsigned char bios[BIOS_BSIZE];   char *match = " ELSA GmbH";   int i,l;      if (xf86ReadBIOS(BIOSbase, 0, bios, BIOS_BSIZE) != BIOS_BSIZE)      return -1;   if ((bios[0] != 0x55) || (bios[1] != 0xaa))      return -2;   l = strlen(match);   for (i=0; i<BIOS_BSIZE-l; i++)       if (bios[i] == match[0] && !memcmp(&bios[i],match,l))	 return 1;   return 0;}#ifdef ELSA_MAINvoid ErrorF(char *s, ...){}void main(){   int i;   int ndata;   unsigned short *data;   unsigned short crc16;   elsa_eeprom_data_t *eedata;   elsa_eeprom_timing_t *eetim;   unsigned long serno;   if (check_ELSA_bios(BIOS_BASE) <= 0) {      printf("no ELSA Bios detected\n");      exit(1);   }   ndata = read_eeprom_data(&data);   if (ndata<0) {      printf("no ELSA Winner card detected\n");      exit(1);   }   crc16 = calc_crc16(ndata,data);   eedata = (elsa_eeprom_data_t *) data;   printf("EEPROM size %d bytes\n",ndata);   if (eedata->crc16 == crc16)      printf("CRC ok (%04x)\n",crc16);   else      printf("CRC not ok (%04x != %04x)\n",eedata->crc16,crc16);   printf("Chip type %s\n"	  ,(eedata->wnr_type == 'S' | '3'<<8) ? "S3" : "unknown");   for (i=0; elsa_board_types[i].code; i++)      if (elsa_board_types[i].code == eedata->board_code) break;   if (elsa_board_types[i].code)      printf("%s\n",elsa_board_types[i].name);   else       printf("unknown ELSA board code %x, please report\n", eedata->board_code);   serno = (eedata->serno_h<<16) | eedata->serno_l;   printf("Ser.No. %c-%04ld.%03ld.%03ld\n",	  (char)('A' + ((serno>>27) & 0x0f)),	  ((serno>>17) & 0x3ff) | ((serno>>21) & 0x400),	  (serno & 0x1ffff) / 1000,	  (serno & 0x1ffff) % 1000);   printf("max pixel clock  %7.3f MHz\n"	  ,(eedata->max_pixclock,eedata->max_pixclock*4)/1000.0);   printf("max memory clock %7.3f MHz\n"	  ,(eedata->max_memclock,eedata->max_memclock*4)/1000.0);   printf("monitor size %d %d\n",eedata->xsize,eedata->ysize);   printf("software version %d\n",eedata->sw_vers);   printf("hardware config %d\n",eedata->hw_conf);   for (i= 26; i<ndata-9; i+=9) {      eetim  = (elsa_eeprom_timing_t *) (data + i);#if 0      printf("\ntiming  %d:\n",i);      printf("\tbpp     %d\n",ELSA_TIM_bpp(*eetim));      printf("\txres    %d\n",ELSA_TIM_xres(*eetim));      printf("\tyres    %d\n",ELSA_TIM_yres(*eetim));      printf("\tpixfrq  %1.3f MHz\n",(ELSA_TIM_pixfrq4(*eetim)*4)/1000.0);      printf("\tflags   %d\n",ELSA_TIM_flags(*eetim));      printf("\thtot    %d\n",ELSA_TIM_htot(*eetim));      printf("\thfp     %d\n",ELSA_TIM_hfp(*eetim));      printf("\thsw     %d\n",ELSA_TIM_hsw(*eetim));      printf("\tvtot    %d\n",ELSA_TIM_vtot(*eetim));      printf("\tvfp     %d\n",ELSA_TIM_vfp(*eetim));      printf("\tvsw     %d\n",ELSA_TIM_vsw(*eetim));#endif      if (ELSA_ET_VM_VALID(eetim))	 printf("\"%dx%dx%d\" \t %7.3f   %4d %4d %4d %4d   %4d %4d %4d %4d\n"	     ,ELSA_TIM_xres(*eetim),ELSA_TIM_yres(*eetim),ELSA_TIM_bpp(*eetim)	     ,(ELSA_TIM_pixfrq4(*eetim)*4)/1000.0	     ,ELSA_TIM_xres(*eetim)	     ,ELSA_TIM_xres(*eetim)+ELSA_TIM_hfp(*eetim)	     ,ELSA_TIM_xres(*eetim)+ELSA_TIM_hfp(*eetim)+ELSA_TIM_hsw(*eetim)	     ,ELSA_TIM_htot(*eetim)	     ,ELSA_TIM_yres(*eetim)	     ,ELSA_TIM_yres(*eetim)+ELSA_TIM_vfp(*eetim)	     ,ELSA_TIM_yres(*eetim)+ELSA_TIM_vfp(*eetim)+ELSA_TIM_vsw(*eetim)	     ,ELSA_TIM_vtot(*eetim)	     );   }      xfree(data);}#elseint s3DetectELSA(int BIOSbase, char **pcard, char **pserno, 		 int *max_pix_clock, int *max_mem_clock, int *hwconfig,		 char **modes){   int i;   int ndata;   unsigned short *data;   unsigned short crc16;   elsa_eeprom_data_t *eedata;   elsa_eeprom_timing_t *eetim;   unsigned long serno;   if (check_ELSA_bios(BIOSbase>0 ? BIOSbase : BIOS_BASE) <= 0) {      return -1;   }   ndata = read_eeprom_data(&data);   if (ndata<0)       return -2;   crc16 = calc_crc16(ndata,data);   eedata = (elsa_eeprom_data_t *) data;   if (eedata->crc16 != crc16) {      xfree(data);      return -3;   }   if (eedata->wnr_type != ('S' | '3'<<8)) {      xfree(data);      return -4;   }   for (i=0; elsa_board_types[i].code; i++)      if (elsa_board_types[i].code == eedata->board_code) break;   if (pcard) {      *pcard  = (char*) xalloc(80);      if (elsa_board_types[i].code)	 sprintf(*pcard,"%s detected",elsa_board_types[i].name);      else 	 sprintf(*pcard,"unknown ELSA Winner board code %04x detected, please report\n"		 , eedata->board_code);   }   if (modes) {      char *p;      p = *modes  = (char*) xalloc(80 * ((ndata-9-26)/9 +1));      *p = '\0';      for (i= 26; i<ndata-9; i+=9) {	 eetim  = (elsa_eeprom_timing_t *) (data + i);	 if (ELSA_ET_VM_VALID(eetim))	    sprintf(p,"\t\"%dx%dx%d\" \t %7.3f   %4d %4d %4d %4d   %4d %4d %4d %4d\n"		    ,ELSA_TIM_xres(*eetim),ELSA_TIM_yres(*eetim),ELSA_TIM_bpp(*eetim)		    ,(ELSA_TIM_pixfrq4(*eetim)*4)/1000.0		    ,ELSA_TIM_xres(*eetim)		    ,ELSA_TIM_xres(*eetim)+ELSA_TIM_hfp(*eetim)		    ,ELSA_TIM_xres(*eetim)+ELSA_TIM_hfp(*eetim)+ELSA_TIM_hsw(*eetim)		    ,ELSA_TIM_htot(*eetim)		    ,ELSA_TIM_yres(*eetim)		    ,ELSA_TIM_yres(*eetim)+ELSA_TIM_vfp(*eetim)		    ,ELSA_TIM_yres(*eetim)+ELSA_TIM_vfp(*eetim)+ELSA_TIM_vsw(*eetim)		    ,ELSA_TIM_vtot(*eetim)		    );	 p += strlen(p);      }      }   if (pserno) {      *pserno = (char*) xalloc(20);      serno = (eedata->serno_h<<16) | eedata->serno_l;      sprintf(*pserno,"%c-%04ld.%03ld.%03ld",	      (char)('A' + ((serno>>27) & 0x0f)),	      ((serno>>17) & 0x3ff) | ((serno>>21) & 0x400),	      (serno & 0x1ffff) / 1000,	      (serno & 0x1ffff) % 1000);   }   if (max_pix_clock)       *max_pix_clock = eedata->max_pixclock * 4;   if (max_mem_clock)       *max_mem_clock = eedata->max_memclock * 4;   if (hwconfig)      *hwconfig = eedata->hw_conf;      i = eedata->board_code;   xfree(data);   return i;}#endif

⌨️ 快捷键说明

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