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

📄 core_irongate.c

📁 ARM 嵌入式 系统 设计与实例开发 实验教材 二源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	       IRONGATE0->pcicfg,	       IRONGATE0->rsrvd6[0],	       IRONGATE0->rsrvd6[1],	       IRONGATE0->rsrvd6[2],	       IRONGATE0->rsrvd6[3],	       IRONGATE0->rsrvd6[4],	       IRONGATE0->agpcap,	       IRONGATE0->agpstat,	       IRONGATE0->agpcmd,	       IRONGATE0->agpva,	       IRONGATE0->agpmode,	       IRONGATE1->dev_vendor,	       IRONGATE1->stat_cmd,	       IRONGATE1->class,	       IRONGATE1->htype,	       IRONGATE1->rsrvd0[0],	       IRONGATE1->rsrvd0[1],	       IRONGATE1->busnos,	       IRONGATE1->io_baselim_regs,	       IRONGATE1->mem_baselim,	       IRONGATE1->pfmem_baselim,	       IRONGATE1->rsrvd1[0],	       IRONGATE1->rsrvd1[1],	       IRONGATE1->io_baselim,	       IRONGATE1->rsrvd2[0],	       IRONGATE1->rsrvd2[1],	       IRONGATE1->interrupt );}#else#define irongate_register_dump(x)#endifintirongate_pci_clr_err(void){	unsigned int nmi_ctl=0;	unsigned int IRONGATE_jd;again:	IRONGATE_jd = IRONGATE0->stat_cmd;	printk("Iron stat_cmd %x\n", IRONGATE_jd);	IRONGATE0->stat_cmd = IRONGATE_jd; /* write again clears error bits */	mb();	IRONGATE_jd = IRONGATE0->stat_cmd;  /* re-read to force write */	IRONGATE_jd = IRONGATE0->dramms;	printk("Iron dramms %x\n", IRONGATE_jd);	IRONGATE0->dramms = IRONGATE_jd; /* write again clears error bits */	mb();	IRONGATE_jd = IRONGATE0->dramms;  /* re-read to force write */	/* Clear ALI NMI */        nmi_ctl = inb(0x61);        nmi_ctl |= 0x0c;        outb(nmi_ctl, 0x61);        nmi_ctl &= ~0x0c;        outb(nmi_ctl, 0x61);	IRONGATE_jd = IRONGATE0->dramms;	if (IRONGATE_jd & 0x300) goto again;	return 0;}void __initirongate_init_arch(void){	struct pci_controller *hose;	IRONGATE0->stat_cmd = IRONGATE0->stat_cmd & ~0x100;	irongate_pci_clr_err();	irongate_register_dump(__FUNCTION__);	/*	 * HACK: set AGP aperture size to 256MB.	 * This should really be changed during PCI probe, when the	 * size of the aperture the AGP card wants is known.	 */	printk("irongate_init_arch: AGPVA was 0x%x\n", IRONGATE0->agpva);	IRONGATE0->agpva = (IRONGATE0->agpva & ~0x0000000f) | 0x00000007;	/*	 * Create our single hose.	 */	pci_isa_hose = hose = alloc_pci_controller();	hose->io_space = &ioport_resource;	hose->mem_space = &iomem_resource;	hose->index = 0;	/* This is for userland consumption.  For some reason, the 40-bit	   PIO bias that we use in the kernel through KSEG didn't work for	   the page table based user mappings.  So make sure we get the	   43-bit PIO bias.  */	hose->sparse_mem_base = 0;	hose->sparse_io_base = 0;	hose->dense_mem_base	  = (IRONGATE_MEM & 0xffffffffff) | 0x80000000000;	hose->dense_io_base	  = (IRONGATE_IO & 0xffffffffff) | 0x80000000000;	hose->sg_isa = hose->sg_pci = NULL;	__direct_map_base = 0;	__direct_map_size = 0xffffffff;}/* * IO map and AGP support */#include <linux/vmalloc.h>#include <asm/pgalloc.h>static inline void irongate_remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, 		     unsigned long phys_addr, unsigned long flags){	unsigned long end;	address &= ~PMD_MASK;	end = address + size;	if (end > PMD_SIZE)		end = PMD_SIZE;	if (address >= end)		BUG();	do {		if (!pte_none(*pte)) {			printk("irongate_remap_area_pte: page already exists\n");			BUG();		}		set_pte(pte, 			mk_pte_phys(phys_addr, 				    __pgprot(_PAGE_VALID | _PAGE_ASM | 					     _PAGE_KRE | _PAGE_KWE | flags)));		address += PAGE_SIZE;		phys_addr += PAGE_SIZE;		pte++;	} while (address && (address < end));}static inline int irongate_remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, 		     unsigned long phys_addr, unsigned long flags){	unsigned long end;	address &= ~PGDIR_MASK;	end = address + size;	if (end > PGDIR_SIZE)		end = PGDIR_SIZE;	phys_addr -= address;	if (address >= end)		BUG();	do {		pte_t * pte = pte_alloc(&init_mm, pmd, address);		if (!pte)			return -ENOMEM;		irongate_remap_area_pte(pte, address, end - address, 				     address + phys_addr, flags);		address = (address + PMD_SIZE) & PMD_MASK;		pmd++;	} while (address && (address < end));	return 0;}static intirongate_remap_area_pages(unsigned long address, unsigned long phys_addr,		       unsigned long size, unsigned long flags){	pgd_t * dir;	unsigned long end = address + size;	phys_addr -= address;	dir = pgd_offset(&init_mm, address);	flush_cache_all();	if (address >= end)		BUG();	do {		pmd_t *pmd;		pmd = pmd_alloc(&init_mm, dir, address);		if (!pmd)			return -ENOMEM;		if (irongate_remap_area_pmd(pmd, address, end - address,					 phys_addr + address, flags))			return -ENOMEM;		address = (address + PGDIR_SIZE) & PGDIR_MASK;		dir++;	} while (address && (address < end));	return 0;}#include <linux/agp_backend.h>#include <linux/agpgart.h>#define GET_PAGE_DIR_OFF(addr) (addr >> 22)#define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr))#define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12) #define GET_GATT(addr) (gatt_pages[GET_PAGE_DIR_IDX(addr)])unsigned longirongate_ioremap(unsigned long addr, unsigned long size){	struct vm_struct *area;	unsigned long vaddr;	unsigned long baddr, last;	u32 *mmio_regs, *gatt_pages, *cur_gatt, pte;	unsigned long gart_bus_addr, gart_aper_size;	gart_bus_addr = (unsigned long)IRONGATE0->bar0 &			PCI_BASE_ADDRESS_MEM_MASK; 	if (!gart_bus_addr) /* FIXME - there must be a better way!!! */		return addr + IRONGATE_MEM;	gart_aper_size = IRONGATE_DEFAULT_AGP_APER_SIZE; /* FIXME */	/* 	 * Check for within the AGP aperture...	 */	do {		/*		 * Check the AGP area		 */		if (addr >= gart_bus_addr && addr + size - 1 < 		    gart_bus_addr + gart_aper_size)			break;		/*		 * Not found - assume legacy ioremap		 */		return addr + IRONGATE_MEM;	} while(0);	mmio_regs = (u32 *)(((unsigned long)IRONGATE0->bar1 &			PCI_BASE_ADDRESS_MEM_MASK) + IRONGATE_MEM);	gatt_pages = (u32 *)(phys_to_virt(mmio_regs[1])); /* FIXME */	/*	 * Adjust the limits (mappings must be page aligned)	 */	if (addr & ~PAGE_MASK) {		printk("AGP ioremap failed... addr not page aligned (0x%lx)\n",		       addr);		return addr + IRONGATE_MEM;	}	last = addr + size - 1;	size = PAGE_ALIGN(last) - addr;#if 0	printk("irongate_ioremap(0x%lx, 0x%lx)\n", addr, size);	printk("irongate_ioremap:  gart_bus_addr  0x%lx\n", gart_bus_addr);	printk("irongate_ioremap:  gart_aper_size 0x%lx\n", gart_aper_size);	printk("irongate_ioremap:  mmio_regs      %p\n", mmio_regs);	printk("irongate_ioremap:  gatt_pages     %p\n", gatt_pages);		for(baddr = addr; baddr <= last; baddr += PAGE_SIZE)	{		cur_gatt = phys_to_virt(GET_GATT(baddr) & ~1);		pte = cur_gatt[GET_GATT_OFF(baddr)] & ~1;		printk("irongate_ioremap:  cur_gatt %p pte 0x%x\n",		       cur_gatt, pte);	}#endif	/*	 * Map it	 */	area = get_vm_area(size, VM_IOREMAP);	if (!area) return (unsigned long)NULL;	for(baddr = addr, vaddr = (unsigned long)area->addr; 	    baddr <= last; 	    baddr += PAGE_SIZE, vaddr += PAGE_SIZE)	{		cur_gatt = phys_to_virt(GET_GATT(baddr) & ~1);		pte = cur_gatt[GET_GATT_OFF(baddr)] & ~1;		if (irongate_remap_area_pages(VMALLOC_VMADDR(vaddr), 					   pte, PAGE_SIZE, 0)) {			printk("AGP ioremap: FAILED to map...\n");			vfree(area->addr);			return (unsigned long)NULL;		}	}	flush_tlb_all();	vaddr = (unsigned long)area->addr + (addr & ~PAGE_MASK);#if 0	printk("irongate_ioremap(0x%lx, 0x%lx) returning 0x%lx\n",	       addr, size, vaddr);#endif	return vaddr;}voidirongate_iounmap(unsigned long addr){	if (((long)addr >> 41) == -2)		return;	/* kseg map, nothing to do */	if (addr) return vfree((void *)(PAGE_MASK & addr)); }

⌨️ 快捷键说明

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