📄 mach64.c
字号:
/* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* THIS DRIVER DOES NOT WORK *//* VGAlib version 1.2 - (c) 1993 Tommy Frandsen *//* *//* This library is free software; you can redistribute it and/or *//* modify it without any restrictions. This library is distributed *//* in the hope that it will be useful, but without any warranty. *//* Multi-chipset support Copyright (C) 1993, 1999 Harm Hanemaayer *//* Initial ATI Mach64 Driver. August 1995. Asad F. Hanif (w81h@unb.ca) Copyright (C) 1995 Asad F. Hanif (w81h@unb.ca) *//* Note: This code is based on the material provided to me by the folks at ATI. As well portions are based on the Mach64 XFree86 Server code. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/mman.h>#include "vga.h"#include "libvga.h"#include "driver.h"#ifdef OSKIT#include "osenv.h"#endif#include "mach64.h"/* globals */static int DUMPINDEX;static char DUMPOUT[33];static US ioBaseAddress, PciIOLocation;static UB cTabSize, *RomLocation;static UL *mreg;static M64_ClockInfo ClockInfo;static M64_MaxColorDepth MaxCDT1[50], MaxCDT2[50], FreqCDT1[50], FreqCDT2[50];static M64_StartUpInfo StartupInfo;/*static CRTC_Table *pcrtc; *//* prototypes *//* svgalib - driverspec functions */static void nothing(void);static int mach64_init(int, int, int);static int mach64_test(void);static int mach64_saveregs(UB *);static void mach64_setregs(const UB *, int);static void mach64_getmodeinfo(int, vga_modeinfo *);static int mach64_modeavailable(int);static int mach64_setmode(int, int);static void mach64_setdisplaystart(int);static void mach64_setlogicalwidth(int);static void mach64_setpage(int);/* misc. functions */static UB *mach64_rom_base(void);static UB *mach64_map_vbios(UB *);/*static void mach64_unmap_vbios(UB *,UB *); */static void mach64_get_alot_of_info(UB *);static void mach64_report(void);/* dac control and programming */#define DAC_TYPE StartupInfo.Dac_Type#define DAC_SUBTYPE StartupInfo.Dac_Subtypestatic int mach64_dac_ati68860(US, US);static void mach64_dac_program(US, US, US);static void mach64_crtc_programming(US, US, US);static void mach64_small_aperature(void);/* regs to save */static int sr_accel[13] ={ioCRTC_GEN_CNTL, ioCRTC_H_SYNC_STRT_WID, ioCRTC_H_TOTAL_DISP, ioCRTC_V_SYNC_STRT_WID, ioCRTC_V_TOTAL_DISP, ioCRTC_OFF_PITCH, ioCLOCK_SEL_CNTL, ioOVR_CLR, ioOVR_WID_LEFT_RIGHT, ioOVR_WID_TOP_BOTTOM, ioMEM_CNTL, ioMEM_VGA_RP_SEL, ioMEM_VGA_WP_SEL};/* Driverspecs function table (exported) */DriverSpecs __svgalib_mach64_driverspecs ={ mach64_saveregs, mach64_setregs, (void (*)(void)) nothing, /* unlock */ (void (*)(void)) nothing, /* lock */ mach64_test, mach64_init, mach64_setpage, /* __svgalib_setpage */ (void (*)(int)) nothing, /* __svgalib_setrdpage */ (void (*)(int)) nothing, /* __svgalib_setwrpage */ mach64_setmode, mach64_modeavailable, mach64_setdisplaystart, mach64_setlogicalwidth, mach64_getmodeinfo, 0, /* bitblt */ 0, /* imageblt */ 0, /* fillblt */ 0, /* hlinelistblt */ 0, /* bltwait */ 0, /* extset */ 0, 0, /* linear */ NULL, /* Accelspecs */ NULL, /* Emulation */};/* empty function */static void nothing(void){}/***************************************************************************//* Initialize chipset */static int mach64_init(int force, int par1, int par2){ UB *atibios; if (__svgalib_driver_report) fprintf(stdout, "Using ATI Mach64 driver.\n"); __svgalib_driverspecs = &__svgalib_mach64_driverspecs; /* Make sure we are operating at IO priveleges are level 3 */ if (iopl(3) < 0) { fprintf(stdout, "iopl(3) failed in Mach64\n"); exit(-1); } /* download configuration data */ atibios = mach64_map_vbios(RomLocation); mach64_get_alot_of_info(atibios);/* This seems to be a cause of segfaults. mach64_unmap_vbios(RomLocation,atibios); */ mach64_report();#ifdef BAILOUT fprintf(stdout, "\n*** WARNING ALPHA DRIVER ***\n" \ "*** If the above diagnostics look ok then press 'Y' to" \ "continue.\n\n"); if (getchar() != 'Y') { fprintf(stdout, "\n*** Bailing out! ***\n"); exit(-1); }#endif return 1;}/* test for presence of mach64 */static int mach64_test(void){ UB *atibios; UB ati_sig1[] = "761295520"; UB ati_sig2[] = "GXCX"; UB ati_sig3[] = "MACH64"; int ati_found, i; UL sv; US romtabptr, *romoff; /* Make sure we are operating at IO privlege level 3 */ if (iopl(3) < 0) { fprintf(stdout, "iopl(3) failed in Mach64\n"); exit(-1); } /* !!should loop through the relocatable bios areas - instead */ /* !!should read the address cause it may be relocateable */ RomLocation = mach64_rom_base(); /* map the vga bios */ atibios = mach64_map_vbios(RomLocation); /* scan for the signature */ ati_found = 0; for (i = 0; i < 128; i++) { if (strncmp(ati_sig1, atibios + i, sizeof(ati_sig1) - 1) == 0) { ati_found = 1; break; } } /* scan for either GXCX or MACH64 */ for (i = 0; i < 1024; i++) { if (strncmp(ati_sig2, atibios + i, sizeof(ati_sig2) - 1) == 0) { ati_found++; break; } if (strncmp(ati_sig3, atibios + i, sizeof(ati_sig3) - 1) == 0) { ati_found++; break; } } /* if its not even ati return a failure */ if (ati_found < 2) return 0; /* grab the address for io access - fixed and relocatable from bios I can't tell if its VLB or PCI yet. If the ioBaseAddress is not 0x2EC, 0x1CC, or 0x1C8 then its obviosly relocatable (we hope). If its relocatable then we pray its PCI. */ romoff = (US *) atibios; romtabptr = romoff[0x48 >> 1]; ioBaseAddress = romoff[(romtabptr >> 1) + 2]; PciIOLocation = romoff[(romtabptr >> 1) + 13]; switch (ioBaseAddress) { case 0x2ec: break; case 0x1cc: case 0x1c8: default: fprintf(stdout, "M64: Can't handle io address %x yet.\n", ioBaseAddress); exit(-1); }#ifdef DEBUG fprintf(stdout, "M64: IO Base Address: %x\n", ioBaseAddress);#endif /* unmap the bios *//* This seems to be the cause of segfaults mach64_unmap_vbios(RomLocation,atibios); */ /* do the scratch register io confirmation test */ /* assume not mach64 */ ati_found = 0; /* save scratch value */ sv = inl(ioSCRATCH_REG0); /* test odd bits for readability */ outl(ioSCRATCH_REG0, 0x55555555); if (inl(ioSCRATCH_REG0) == 0x55555555) { /* test even bits for readability */ outl(ioSCRATCH_REG0, 0xaaaaaaaa); if (inl(ioSCRATCH_REG0) == 0xaaaaaaaa) { ati_found = 1; } } /* restore */ outl(ioSCRATCH_REG0, sv); return (ati_found) ? mach64_init(0, 0, 0) : ati_found;}/**************************************************************************//* locate rom locatation */static UB *mach64_rom_base(void){ US a; UB *b; a = inw(ioSCRATCH_REG1); a &= 0x7f; a += 0xc000; b = (UB *) (a * 0x10); return (b);}/* map the vga bios - pretty much lifted from ati.c */static UB *mach64_map_vbios(UB * map_me){ UB *vga_bios; /* allocate 32k for bios map */#ifdef OSKIT osenv_mem_map_phys(map_me, M64_BIOS_SIZE, &vga_bios, 0);#else if ((vga_bios = valloc(M64_BIOS_SIZE)) == NULL) { fprintf(stdout, "SVGALIB valloc failure\n"); exit(-1); } vga_bios = (UB *) mmap((caddr_t) vga_bios, M64_BIOS_SIZE, PROT_READ, MAP_SHARED | MAP_FIXED, __svgalib_mem_fd, (off_t) map_me);#endif if ((long) vga_bios < 0) { fprintf(stdout, "SVGALIB mmap failure\n"); exit(-1); } return (UB *) vga_bios;}/* static void mach64_unmap_vbios(UB *unmap_me,UB *free_me) { if (munmap((caddr_t)unmap_me,M64_BIOS_SIZE)) { fprintf(stdout,"SVGALIB munmap failure\n"); exit(-1); } free((void *)free_me); } *//****************************************************************************//* collect information from rom and registers */static void mach64_get_alot_of_info(UB * mapped_area){ UB *bbios; US *sbios; int i, j; US RomTableOff, FreqTablePtr, CdepthTablePtr; UL RegL; UB RegB; UB mask; /* setup bios area mappings and initial offsets */ sbios = (US *) mapped_area; bbios = (UB *) mapped_area; RomTableOff = sbios[0x48 >> 1]; FreqTablePtr = sbios[(RomTableOff >> 1) + 8]; /* grab the CONFIG_CHIP_ID information */ RegL = inl(ioCONFIG_CHIP_ID); StartupInfo.Chip_Type = (US) (RegL & 0xffff); StartupInfo.Chip_Class = (UB) ((RegL >> 16) && 0xff); StartupInfo.Chip_Rev = (UB) ((RegL >> 24) && 0xff); switch (StartupInfo.Chip_Type) { case 0xd7: if (StartupInfo.Chip_Rev <= 0x03) StartupInfo.Chip_ID_Index = StartupInfo.Chip_Rev; else StartupInfo.Chip_ID_Index = 0x04; break; case 0x57: if (StartupInfo.Chip_Rev == 0x01) StartupInfo.Chip_ID_Index = 0x05; else StartupInfo.Chip_ID_Index = 0x06; break; case 0x4354: StartupInfo.Chip_ID_Index = 0x07; break; case 0x4554: StartupInfo.Chip_ID_Index = 0x08; break; default: StartupInfo.Chip_ID_Index = 0x09; }#ifdef REPORT if (StartupInfo.Chip_ID_Index < 0x07) fprintf(stdout, "M64: ATI Mach64 88800 %s detected.\n", M64_Chip_Name[StartupInfo.Chip_ID_Index]); else fprintf(stdout, "M64: ATI Mach64 88800 %s Rev. %x detected.\n", M64_Chip_Name[StartupInfo.Chip_ID_Index], StartupInfo.Chip_Rev);#endif /* read the CONFIG_STAT0 and CONFIG_STAT1 */ RegL = inl(ioCONFIG_STAT0); StartupInfo.Cfg_Bus_type = (UB) (RegL & 0x07); StartupInfo.Cfg_Ram_type = (UB) ((RegL >> 3) & 0x7); RegL = inl(ioCONFIG_STAT1);#ifdef REPORT fprintf(stdout, "M64: Bus Type: %s\n", M64_Bus_Name[StartupInfo.Cfg_Bus_type]); fprintf(stdout, "M64: Memory Type: %s\n", M64_Ram_Name[StartupInfo.Cfg_Ram_type]);#endif /* read memory configurations stuff */ RegL = inl(ioMEM_CNTL); StartupInfo.Mem_Size = (UB) (RegL & 0x07);#ifdef REPORT fprintf(stdout, "M64: Memory Installed: %d Kilobytes\n", M64_Mem_Size[StartupInfo.Mem_Size]);#endif /* read the dac type and sub type */ RegB = inb(ioDAC_CNTL + 2); StartupInfo.Dac_Type = RegB & 0x07; RegB = inb(ioSCRATCH_REG1 + 1); StartupInfo.Dac_Subtype = (RegB & 0xf0) | StartupInfo.Dac_Type;#ifdef REPORT fprintf(stdout, "M64: Dac Type: %d %s Sub Type: %d\n", StartupInfo.Dac_Type, M64_Dac_Name[StartupInfo.Dac_Type], StartupInfo.Dac_Subtype);#endif /* grab a pile of clock info */ ClockInfo.ClockType = bbios[FreqTablePtr + 0]; ClockInfo.MinFreq = sbios[(FreqTablePtr >> 1) + 1]; ClockInfo.MaxFreq = sbios[(FreqTablePtr >> 1) + 2]; ClockInfo.RefFreq = sbios[(FreqTablePtr >> 1) + 4]; ClockInfo.RefDivdr = sbios[(FreqTablePtr >> 1) + 5]; ClockInfo.N_adj = sbios[(FreqTablePtr >> 1) + 6]; ClockInfo.Dram_Mem_Clk = sbios[(FreqTablePtr >> 1) + 8]; ClockInfo.Vram_Mem_Clk = sbios[(FreqTablePtr >> 1) + 9]; ClockInfo.Coproc_Mem_Clk = sbios[(FreqTablePtr >> 1) + 12]; ClockInfo.CX_Clk = bbios[FreqTablePtr + 6]; ClockInfo.VGA_Clk = bbios[FreqTablePtr + 7]; ClockInfo.Mem_Clk_Entry = bbios[FreqTablePtr + 22]; ClockInfo.SClk_Entry = bbios[FreqTablePtr + 23]; ClockInfo.CX_DMcycle = bbios[RomTableOff + 0]; ClockInfo.VGA_DMcycle = bbios[RomTableOff + 0]; ClockInfo.CX_VMcycle = bbios[RomTableOff + 0]; ClockInfo.VGA_VMcycle = bbios[RomTableOff + 0]; CdepthTablePtr = sbios[(FreqTablePtr >> 1) - 3]; FreqTablePtr = sbios[(FreqTablePtr >> 1) - 1]; FreqTablePtr >>= 1; /* Read the default clocks */ for (i = 0; i <= M64_CLOCK_MAX; i++) ClockInfo.ClkFreqTable[i] = sbios[FreqTablePtr + i]; /* grab the color depth tables */ cTabSize = bbios[CdepthTablePtr - 1];#ifdef REPORT fprintf(stdout, "M64: ClockType: %d %s\n", ClockInfo.ClockType, M64_Clock_Name[ClockInfo.ClockType]); fprintf(stdout, "M64: MinFreq: %d\n", ClockInfo.MinFreq); fprintf(stdout, "M64: MaxFreq: %d\n", ClockInfo.MaxFreq); fprintf(stdout, "M64: RefFreq: %d\n", ClockInfo.RefFreq); fprintf(stdout, "M64: RefDivdr: %d\n", ClockInfo.RefDivdr); fprintf(stdout, "M64: N_adj: %d\n", ClockInfo.N_adj); fprintf(stdout, "M64: DramMemClk: %d\n", ClockInfo.Dram_Mem_Clk); fprintf(stdout, "M64: VramMemClk: %d\n", ClockInfo.Vram_Mem_Clk); fprintf(stdout, "M64: CoprocMemClk: %d\n", ClockInfo.Coproc_Mem_Clk); fprintf(stdout, "M64: CX_Clk: %d\n", ClockInfo.CX_Clk); fprintf(stdout, "M64: VGA_Clk: %d\n", ClockInfo.VGA_Clk); fprintf(stdout, "M64: Mem_Clk_Entry: %d\n", ClockInfo.Mem_Clk_Entry); fprintf(stdout, "M64: SClk_Entry: %d\n", ClockInfo.SClk_Entry); fprintf(stdout, "M64: V/D_MCycle: %d\n", ClockInfo.CX_DMcycle); for (i = 0; i <= M64_CLOCK_MAX; i++) { if (i % 8 == 0) fprintf(stdout, "\nM64: Clocks: "); fprintf(stdout, "%d.%d ", ClockInfo.ClkFreqTable[i] / 100, ClockInfo.ClkFreqTable[i] % 100); } fprintf(stdout, "\n");#endif /* Get color depth tables that are valid for current dac */ mask = 1 << StartupInfo.Dac_Type; for (j = i = 0; bbios[CdepthTablePtr + i] != 0; i += cTabSize) { if (bbios[CdepthTablePtr + i + 1] & mask) { MaxCDT1[j].h_disp = bbios[CdepthTablePtr + i]; MaxCDT1[j].dacmask = bbios[CdepthTablePtr + i + 1]; MaxCDT1[j].ram_req = bbios[CdepthTablePtr + i + 2]; MaxCDT1[j].max_dot_clk = bbios[CdepthTablePtr + i + 3]; MaxCDT1[j].color_depth = bbios[CdepthTablePtr + i + 4]; ++j; } } MaxCDT1[j].h_disp = 0; /* Get second color depth table if exists that are valid subtype */ CdepthTablePtr += i + 2; cTabSize = bbios[CdepthTablePtr - 1]; for (j = i = 0; bbios[CdepthTablePtr + i] != 0; i += cTabSize) { if (bbios[CdepthTablePtr + i + 1] == StartupInfo.Dac_Subtype) { MaxCDT2[j].h_disp = bbios[CdepthTablePtr + i]; MaxCDT2[j].dacmask = bbios[CdepthTablePtr + i + 1]; MaxCDT2[j].ram_req = bbios[CdepthTablePtr + i + 2]; MaxCDT2[j].max_dot_clk = bbios[CdepthTablePtr + i + 3]; MaxCDT2[j].color_depth = bbios[CdepthTablePtr + i + 4]; ++j; fprintf(stdout, "%d\n", j); } } MaxCDT2[j].h_disp = 0; /* Filter out the useless entries based on bpp and memory */ mask = StartupInfo.Cfg_Ram_type & VRAM_MASK; mask = (mask) ? 4 : 0; /* table 1 */ for (i = 0, j = 0; MaxCDT1[i].h_disp != 0; i++) { /* pick out 8 bpp modes for now */ switch (MaxCDT1[i].color_depth) { case BPP_8: if ((MaxCDT1[i].ram_req >> mask) > StartupInfo.Mem_Size) break; FreqCDT1[j].h_disp = MaxCDT1[i].h_disp; FreqCDT1[j].dacmask = MaxCDT1[i].dacmask; FreqCDT1[j].ram_req = MaxCDT1[i].ram_req; FreqCDT1[j].max_dot_clk = MaxCDT1[i].max_dot_clk; FreqCDT1[j].color_depth = MaxCDT1[i].color_depth; j++; break; case BPP_32: case BPP_16: case BPP_15:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -