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

📄 mem_controller.c

📁 ati driver
💻 C
字号:
/*	Copyright (c) 2002, Thomas Kurschel		Part of Radeon kernel driver			Memory controller setup.		The memory controller of the Radeon provides a universal mapping	from addresses generated by the different DMA units within the	graphics chip to addresses in local/PCI/AGP memory. Here, we	set this mapping up.		Further we initialize some bus controller registers here (where bus	means non-local memory interface).*/#include "radeon_driver.h"#include "../regs/buscntrl_regs.h"#include "../shared/mmio.h"#include "../regs/memcntrl_regs.h"// get last RAM address + 1, i.e. first unused physical addressstatic uint32 getTopOfRam(){	system_info info;	// there is no function to really get this info;	// as a hack, we ask for number of physical RAM pages and hope	// they are contigous, starting at address 0		get_system_info( &info );		return info.max_pages * 4096;}// graphics card addresses correspond to physical CPU addresses as much as possiblestatic void Radeon_SetupMCAddresses_Direct( device_info *di ){	shared_info *si = di->si;		// set address range of video memory;	// use the same addresses the CPU sees	si->memory[mt_local].virtual_addr_start = (uint32)si->framebuffer_pci;	si->memory[mt_local].virtual_size = di->local_mem_size;	// PCI GART has no corresponding CPU address space, so we must find an unused	// one; we assume that the addresses directly after physical RAM are	// not in use as the BIOS should have allocated address for PCI devices	// starting with highest address possible. 	// no problem in terms of alignment: it must be a multiple 4K only	si->memory[mt_PCI].virtual_addr_start = (getTopOfRam() + 4095) & ~4095;	si->memory[mt_PCI].virtual_size = ATI_MAX_PCIGART_PAGES * ATI_PCIGART_PAGE_SIZE;	// similar problem with AGP: though there _is_ a corresponding CPU address space,	// we don't know it (this would require finding the AGP bridge and	// getting info from there, which would be a dangerous hack);	// solution is to locate AGP aperture directly after PCI GART;	// we define a 4 MB aperture to meet any possible alignment restrictions	si->memory[mt_AGP].virtual_addr_start = 		(si->memory[mt_PCI].virtual_addr_start + si->memory[mt_PCI].virtual_size		+ 0x3fffff) & ~0x3fffff;	si->memory[mt_AGP].virtual_size = 0x400000;}#if 0// graphics card addresses are mapped in a way to restrict direct main memory accessstatic void Radeon_SetupMCAddresses_Safe( device_info *di ){	shared_info *si = di->si;	// any address not covered by frame buffer, PCI GART or AGP aperture	// leads to a direct memory access	// -> this is dangerous, so we make sure entire address space is mapped		// locate PCI GART at top of address space	// warning about size: there are quite strong alignment restrictions,	// so we better obey!	si->memory[mt_PCI].virtual_size = ATI_MAX_PCIGART_PAGES * ATI_PCIGART_PAGE_SIZE;	si->memory[mt_PCI].virtual_addr_start = 0 - si->memory[mt_PCI].virtual_size;		// let AGP range overlap with frame buffer to hide it;	// according to spec, frame buffer should win but we better	// choose an unused-area to avoid trouble	// (specs don't talk about overlapping area, let's hope	// the memory controller won't choke if we ever access it)	si->memory[mt_AGP].virtual_size = 0x400000;	si->memory[mt_AGP].virtual_addr_start = 		si->memory[mt_PCI].virtual_addr_start - 		si->memory[mt_AGP].virtual_size;	// set address range of video memory	// let it cover all remaining addresses; 	// addresses are wrapped 	si->memory[mt_local].virtual_addr_start = 0;	si->memory[mt_local].virtual_size = 		si->memory[mt_AGP].virtual_addr_start -		si->memory[mt_local].virtual_addr_start;}#endif// graphics cards addresses are mapped IGP compliantlystatic void Radeon_SetupMCAddresses_IGP( device_info *di ){	shared_info *si = di->si;	uint32 tom;		// the frame buffer memory address range is read from TOM register	// it located at end of physical RAM (at least it seems so)	tom = INREG( di->regs, RADEON_GC_NB_TOM );	si->memory[mt_local].virtual_addr_start = (tom & 0xffff) << 16;	si->memory[mt_local].virtual_size =		(((tom >> 16) + 1) << 16) -		si->memory[mt_local].virtual_addr_start;	// after the frame buffer, physical memory should end and unused	// physical addresses start - good location to put the PCI GART to	si->memory[mt_PCI].virtual_addr_start = ((((tom >> 16) + 1) << 16) + 4095) & ~4095;	si->memory[mt_PCI].virtual_size = ATI_MAX_PCIGART_PAGES * ATI_PCIGART_PAGE_SIZE;	// locate AGP aperture after PCI GART	si->memory[mt_AGP].virtual_addr_start = 		(si->memory[mt_PCI].virtual_addr_start + 		si->memory[mt_PCI].virtual_size + 0x3fffff) & ~0x3fffff;	si->memory[mt_AGP].virtual_size = 0x400000;}void Radeon_InitMemController( device_info *di ){	vuint8 *regs = di->regs;	shared_info *si = di->si;	if( di->is_igp )		Radeon_SetupMCAddresses_IGP( di );	else		Radeon_SetupMCAddresses_Direct/*Radeon_SetupMCAddresses_Safe*/( di );	SHOW_INFO0( 3, "Graphics card address mapping:" );	SHOW_INFO( 3, " local memory 0x%lx@0x%lx", 		si->memory[mt_local].virtual_size, si->memory[mt_local].virtual_addr_start );	SHOW_INFO( 3, " PCI GART 0x%lx@0x%lx", 		si->memory[mt_PCI].virtual_size, si->memory[mt_PCI].virtual_addr_start );	SHOW_INFO( 3, " disabled AGP GART 0x%lx@0x%lx", 		si->memory[mt_AGP].virtual_size, si->memory[mt_AGP].virtual_addr_start );		//si->nonlocal_mem = di->DMABuffer.ptr;			// set PCI GART page-table base address	OUTREG( regs, RADEON_AIC_PT_BASE, di->pci_gart.GATT.phys );	// set address range for PCI address translation	// we must restrict range to the actually used GART size here!	OUTREG( regs, RADEON_AIC_LO_ADDR, si->memory[mt_PCI].virtual_addr_start );	OUTREG( regs, RADEON_AIC_HI_ADDR, si->memory[mt_PCI].virtual_addr_start + 		si->memory[mt_PCI].virtual_size/*di->pci_gart.buffer.size*/ - 1 );	// set AGP address range	OUTREG( regs, RADEON_MC_AGP_LOCATION, 		(si->memory[mt_AGP].virtual_addr_start >> 16) |		((si->memory[mt_AGP].virtual_addr_start + si->memory[mt_AGP].virtual_size - 1) & 0xffff0000 ));		// set address range of video memory	// (lower word = begin >> 16	//  upper word = end >> 16)	OUTREG( regs, RADEON_MC_FB_LOCATION,		((si->memory[mt_local].virtual_addr_start + si->memory[mt_local].virtual_size - 1) & 0xffff0000) |		 (si->memory[mt_local].virtual_addr_start >> 16) );		 	// base address of CRTC and others must be same as frame buffer address	// (we could specify any address too, but local memory is of course first choice)	OUTREG( regs, RADEON_DISPLAY_BASE_ADDRESS, si->memory[mt_local].virtual_addr_start );	OUTREG( regs, RADEON_CRTC2_DISPLAY_BASE_ADDRESS, si->memory[mt_local].virtual_addr_start );	OUTREG( regs, RADEON_OV0_BASE_ADDRESS, si->memory[mt_local].virtual_addr_start );	// disable AGP	OUTREG( regs, RADEON_AGP_COMMAND, 0 );		 	// Turn on PCI GART	OUTREGP( regs, RADEON_AIC_CNTL, RADEON_PCIGART_TRANSLATE_EN, 		~RADEON_PCIGART_TRANSLATE_EN );	// fix some bus controller setting	// I reckon this takes care of discarding data unnecessarily read 	// during a burst; let's hope this will fix the nasty CP crashing problem	OUTREGP( regs, RADEON_BUS_CNTL, RADEON_BUS_RD_DISCARD_EN, ~RADEON_BUS_RD_DISCARD_EN );	//	SHOW_FLOW0( 3, "done" );}

⌨️ 快捷键说明

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