📄 bios.c
字号:
di->fp_info.h_over_plus = ((fpi_timing.h_sync_start & 0xfff) - fpi_timing.h_display - 1) * 8; di->fp_info.h_sync_width = fpi_timing.h_sync_width * 8; di->fp_info.v_blank = fpi_timing.v_total - fpi_timing.v_display; di->fp_info.v_over_plus = (fpi_timing.v_sync & 0x7ff) - fpi_timing.v_display; di->fp_info.v_sync_width = (fpi_timing.v_sync & 0xf800) >> 11; di->fp_info.dot_clock = fpi_timing.dot_clock * 10; return true; } SHOW_ERROR0( 2, "Radeon: couldn't get Panel Timing from BIOS" ); return false;}// try to reverse engineer DFP specification from // timing currently set up in graphics cards registers// (effectively, we hope that BIOS has set it up correctly// and noone has messed registers up yet; let's pray)static void Radeon_RevEnvDFPSize( device_info *di ){ vuint8 *regs = di->regs; di->fp_info.panel_yres = ((INREG( regs, RADEON_FP_VERT_STRETCH ) & RADEON_VERT_PANEL_SIZE) >> RADEON_VERT_PANEL_SIZE_SHIFT) + 1; di->fp_info.panel_xres = (((INREG( regs, RADEON_FP_HORZ_STRETCH ) & RADEON_HORZ_PANEL_SIZE) >> RADEON_HORZ_PANEL_SIZE_SHIFT) + 1) * 8; SHOW_INFO( 2, "detected panel size from registers: %dx%d", di->fp_info.panel_xres, di->fp_info.panel_yres);}// once more for getting precise timingstatic void Radeon_RevEnvDFPTiming( device_info *di ){ vuint8 *regs = di->regs; uint32 r; uint16 a, b; r = INREG( regs, RADEON_FP_CRTC_H_TOTAL_DISP ); // the magic "4" was found by trial and error and probably stems from fudge (see crtc.c) a = (r & RADEON_FP_CRTC_H_TOTAL_MASK)/* + 4*/; b = (r & RADEON_FP_CRTC_H_DISP_MASK) >> RADEON_FP_CRTC_H_DISP_SHIFT; di->fp_info.h_blank = (a - b) * 8; SHOW_FLOW( 2, "h_total=%d, h_disp=%d", a * 8, b * 8 ); r = INREG( regs, RADEON_FP_H_SYNC_STRT_WID ); di->fp_info.h_over_plus = ((r & RADEON_FP_H_SYNC_STRT_CHAR_MASK) >> RADEON_FP_H_SYNC_STRT_CHAR_SHIFT) - b/* - 1*/; di->fp_info.h_over_plus *= 8; di->fp_info.h_sync_width = ((r & RADEON_FP_H_SYNC_WID_MASK) >> RADEON_FP_H_SYNC_WID_SHIFT); // TBD: this seems to be wrong // (my BIOS tells 112, this calculation leads to 24!) di->fp_info.h_sync_width *= 8; r = INREG( regs, RADEON_FP_CRTC_V_TOTAL_DISP ); a = (r & RADEON_FP_CRTC_V_TOTAL_MASK)/* + 1*/; b = (r & RADEON_FP_CRTC_V_DISP_MASK) >> RADEON_FP_CRTC_V_DISP_SHIFT; di->fp_info.v_blank = a - b; SHOW_FLOW( 2, "v_total=%d, v_disp=%d", a, b ); r = INREG( regs, RADEON_FP_V_SYNC_STRT_WID ); di->fp_info.v_over_plus = (r & RADEON_FP_V_SYNC_STRT_MASK) - b; di->fp_info.v_sync_width = ((r & RADEON_FP_V_SYNC_WID_MASK) >> RADEON_FP_V_SYNC_WID_SHIFT)/* + 1*/; // standard CRTC r = INREG( regs, RADEON_CRTC_H_TOTAL_DISP ); a = (r & RADEON_CRTC_H_TOTAL); b = (r & RADEON_CRTC_H_DISP) >> RADEON_CRTC_H_DISP_SHIFT; di->fp_info.h_blank = (a - b) * 8; SHOW_FLOW( 2, "h_total=%d, h_disp=%d", a * 8, b * 8 ); r = INREG( regs, RADEON_CRTC_H_SYNC_STRT_WID ); di->fp_info.h_over_plus = ((r & RADEON_CRTC_H_SYNC_STRT_CHAR) >> RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT) - b; di->fp_info.h_over_plus *= 8; di->fp_info.h_sync_width = ((r & RADEON_CRTC_H_SYNC_WID) >> RADEON_CRTC_H_SYNC_WID_SHIFT); di->fp_info.h_sync_width *= 8; r = INREG( regs, RADEON_CRTC_V_TOTAL_DISP ); a = (r & RADEON_CRTC_V_TOTAL); b = (r & RADEON_CRTC_V_DISP) >> RADEON_CRTC_V_DISP_SHIFT; di->fp_info.v_blank = a - b; SHOW_FLOW( 2, "v_total=%d, v_disp=%d", a, b ); r = INREG( regs, RADEON_CRTC_V_SYNC_STRT_WID ); di->fp_info.v_over_plus = (r & RADEON_CRTC_V_SYNC_STRT) - b; di->fp_info.v_sync_width = ((r & RADEON_CRTC_V_SYNC_WID) >> RADEON_CRTC_V_SYNC_WID_SHIFT);}/*// get everything in terms of monitors connected to the cardstatic void Radeon_GetBIOSMon( device_info *di ){ Radeon_GetMonType( di ); // reset all Flat Panel Info; // it gets filled out step by step, and this way we know what's still missing memset( &di->fp_info, 0, sizeof( di->fp_info )); // we assume that the only fp port is combined with standard port 0 di->fp_info.disp_type = di->disp_type[0]; if( di->is_mobility ) { // there is a flat panel - get info about it Radeon_GetBIOSDFPInfo( di ); // if BIOS doesn't know, ask the registers if( di->fp_info.panel_xres == 0 || di->fp_info.panel_yres == 0) Radeon_RevEnvDFPSize( di ); if( di->fp_info.h_blank == 0 || di->fp_info.v_blank == 0) Radeon_RevEnvDFPTiming( di ); SHOW_INFO( 2, "h_disp=%d, h_blank=%d, h_over_plus=%d, h_sync_width=%d", di->fp_info.panel_xres, di->fp_info.h_blank, di->fp_info.h_over_plus, di->fp_info.h_sync_width ); SHOW_INFO( 2, "v_disp=%d, v_blank=%d, v_over_plus=%d, v_sync_width=%d", di->fp_info.panel_yres, di->fp_info.v_blank, di->fp_info.v_over_plus, di->fp_info.v_sync_width ); SHOW_INFO( 2, "pixel_clock=%d", di->fp_info.dot_clock ); }}*/// get info about Laptop flat panelstatic void Radeon_GetFPData( device_info *di ){ // reset all Flat Panel Info; // it gets filled out step by step, and this way we know what's still missing memset( &di->fp_info, 0, sizeof( di->fp_info )); // we only use BIOS for Laptop flat panels if( !di->is_mobility ) return; // ask BIOS about flat panel spec Radeon_GetBIOSDFPInfo( di ); // if BIOS doesn't know, ask the registers if( di->fp_info.panel_xres == 0 || di->fp_info.panel_yres == 0) Radeon_RevEnvDFPSize( di ); if( di->fp_info.h_blank == 0 || di->fp_info.v_blank == 0) Radeon_RevEnvDFPTiming( di ); SHOW_INFO( 2, "h_disp=%d, h_blank=%d, h_over_plus=%d, h_sync_width=%d", di->fp_info.panel_xres, di->fp_info.h_blank, di->fp_info.h_over_plus, di->fp_info.h_sync_width ); SHOW_INFO( 2, "v_disp=%d, v_blank=%d, v_over_plus=%d, v_sync_width=%d", di->fp_info.panel_yres, di->fp_info.v_blank, di->fp_info.v_over_plus, di->fp_info.v_sync_width ); SHOW_INFO( 2, "pixel_clock=%d", di->fp_info.dot_clock );}// detect amount of graphics memoryvoid Radeon_DetectRAM( device_info *di ){ vuint8 *regs = di->regs; if( !di->is_igp ) di->local_mem_size = INREG( regs, RADEON_CONFIG_MEMSIZE ) & RADEON_CONFIG_MEMSIZE_MASK; else { uint32 tom; tom = INREG( regs, RADEON_GC_NB_TOM ); di->local_mem_size = ((tom >> 16) + 1 - (tom & 0xffff)) << 16; } // some production boards of m6 will return 0 if it's 8 MB if( di->local_mem_size == 0 ) di->local_mem_size = 8 * 1024 *1024; switch( INREG( regs, RADEON_MEM_SDRAM_MODE_REG ) & RADEON_MEM_CFG_TYPE_MASK ) { case RADEON_MEM_CFG_SDR: // SDR SGRAM (2:1) strcpy(di->ram_type, "SDR SGRAM"); di->ram.ml = 4; di->ram.MB = 4; di->ram.Trcd = 1; di->ram.Trp = 2; di->ram.Twr = 1; di->ram.CL = 2; di->ram.loop_latency = 16; di->ram.Rloop = 16; di->ram.Tr2w = 0; break; case RADEON_MEM_CFG_DDR: // DDR SGRAM strcpy(di->ram_type, "DDR SGRAM"); di->ram.ml = 4; di->ram.MB = 4; di->ram.Trcd = 3; di->ram.Trp = 3; di->ram.Twr = 2; di->ram.CL = 3; di->ram.Tr2w = 1; di->ram.loop_latency = 16; di->ram.Rloop = 16; break; // only one bit, so there's no default } SHOW_INFO( 1, "%ld MB %s found", di->local_mem_size / 1024 / 1024, di->ram_type ); /* if( di->local_mem_size > 64 * 1024 * 1024 ) { di->local_mem_size = 64 * 1024 * 1024; SHOW_INFO0( 1, "restricted to 64 MB" ); }*/}// map and verify card's BIOS to see whether this really is a Radeon// (as we need BIOS for further info we have to make sure we use the right one)status_t Radeon_MapBIOS( pci_info *pcii, rom_info *ri ){ char buffer[100]; sprintf(buffer, "%04X_%04X_%02X%02X%02X bios", pcii->vendor_id, pcii->device_id, pcii->bus, pcii->device, pcii->function); // we only scan BIOS at legacy location in first MB; // using the PCI location would improve detection, especially // if multiple graphics cards are installed // BUT: BeOS uses the first graphics card it finds (sorted by // device name), thus you couldn't choose in BIOS which card // to use; checking the legacy location ensures that the card is // only detected if it's the primary card ri->phys_address = 0xc0000; ri->size = 0x40000; ri->bios_area = map_physical_memory( buffer, (void *)ri->phys_address, ri->size, B_ANY_KERNEL_ADDRESS, B_READ_AREA, (void **)&ri->bios_ptr ); if( ri->bios_area < 0 ) return ri->bios_area; ri->rom_ptr = Radeon_FindRom( ri ); // on success, adjust physical address to found ROM if( ri->rom_ptr != NULL ) ri->phys_address += ri->rom_ptr - ri->bios_ptr; return ri->rom_ptr != NULL ? B_OK : B_ERROR;}// unmap card's BIOSvoid Radeon_UnmapBIOS( rom_info *ri ){ delete_area( ri->bios_area ); ri->bios_ptr = ri->rom_ptr = NULL;}// get everything valuable from BIOS (BIOS must be mapped)status_t Radeon_ReadBIOSData( device_info *di ){ shared_info dummy_si; status_t result = B_OK; // give Radeon_MapDevice something to play with di->si = &dummy_si; // don't map frame buffer - we don't know its proper size yet! result = Radeon_MapDevice( di, true ); if( result < 0 ) goto err1; Radeon_GetPLLInfo( di ); Radeon_GetFPData( di ); Radeon_DetectRAM( di ); Radeon_UnmapDevice( di ); err1: di->si = NULL; return result;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -