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

📄 safl.c

📁 Intel XScale PXA255 引导Linux的Redboot 版bootloader源代码!
💻 C
字号:
// #========================================================================// #// #    safl.c// #// #    Linux driver for Intel(R) StrongARM(R) PCI-based coprocessor boards.// #// #========================================================================// ####COPYRIGHTBEGIN####//                                                                          // -------------------------------------------                              // The contents of this file are subject to the Red Hat eCos Public License // Version 1.1 (the "License"); you may not use this file except in         // compliance with the License.  You may obtain a copy of the License at    // http://www.redhat.com/                                                   //                                                                          // Software distributed under the License is distributed on an "AS IS"      // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the // License for the specific language governing rights and limitations under // the License.                                                             //                                                                          // The Original Code is eCos - Embedded Configurable Operating System,      // released September 30, 1998.                                             //                                                                          // The Initial Developer of the Original Code is Red Hat.                   // Portions created by Red Hat are                                          // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             // All Rights Reserved.                                                     // -------------------------------------------                              //                                                                          // ####COPYRIGHTEND####// #========================================================================// ######DESCRIPTIONBEGIN####// #// # Author(s):     msalter// # Contributors:  msalter// # Date:          1999-04-02// # Purpose:       Linux driver for Intel(R) StrongARM(R) PCI-based// #                coprocessor boards// # Description:   This module currently supports EBSA-285 and SA-IOP.// #                Intel is a Registered Trademark of Intel Corporation.// #                StrongARM is a Registered Trademark of Advanced RISC// #                Machines Limited.// #                Other Brands and Trademarks are the property of their// #                respective owners.// #// #####DESCRIPTIONEND####// #// #========================================================================static char *version ="safl.c:v0.01H 04/02/99 Mark Salter, Red Hat.\n";#include <linux/module.h>#include <linux/config.h>#include <linux/version.h>#ifdef MODVERSIONS#include <linux/modversions.h>#endif#include <linux/types.h>#include <linux/errno.h>#include <linux/kernel.h>#include <linux/miscdevice.h>#include <linux/malloc.h>#include <linux/mm.h>#include <linux/pci.h>#include <linux/signal.h>#include <linux/ioport.h>#include <linux/fcntl.h>#include <asm/pgtable.h>#include <asm/page.h>#include <linux/sched.h>#include <asm/segment.h>#ifdef CONFIG_PROC_FS#include <linux/proc_fs.h>#endif#include <asm/io.h>#include <asm/system.h>#if LINUX_VERSION_CODE >= 0x020100#include <linux/init.h>#include <linux/vmalloc.h>#else#include <linux/bios32.h>#define __initfunc(x) x#endif#if LINUX_VERSION_CODE < 0x20155#define PCI_SUPPORT_VER1#else#define PCI_SUPPORT_VER2#endif#if defined(MODULE) && LINUX_VERSION_CODE > 0x20115MODULE_AUTHOR("Mark Salter <msalter@redhat.com>");MODULE_DESCRIPTION("Intel(R) StrongARM(R) FLASH driver for PCI EVBs");#endif/* This isn't in /usr/include/linux/pci.h */#ifndef PCI_DEVICE_ID_DEC_IOP#define PCI_DEVICE_ID_DEC_21554     0x46#endif#ifndef PCI_DEVICE_ID_DEC_21285#define PCI_DEVICE_ID_DEC_21285	    0x1065#endif/* somewhat arbitrary minor number. Major number is 10 (misc). */#define SAFL_MINOR 178#define FLASH_SZ   (4 * 1024 * 1024)static int safl_open( struct inode *inode, struct file *file );static int safl_close( struct inode *inode, struct file *file );#if LINUX_VERSION_CODE >= 0x020100static int safl_mmap(struct file * file, struct vm_area_struct * vma);#elsestatic int safl_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma);#endifstatic int safl_debug = 0;static unsigned long csr_ioaddr;static unsigned long flash_addr;static struct file_operations safl_fops = {    NULL,                       /* lseek */    NULL,                       /* read  */    NULL,                       /* write */    NULL,			/* readdir */    NULL,			/* poll */    NULL,                       /* ioctl */    safl_mmap,			/* mmap */    safl_open,                  /* open */    NULL,			/* flush */    safl_close                  /* close */};static struct miscdevice safl_dev = {	SAFL_MINOR,	"SA-FLASH",	&safl_fops};/* PCI configuration space information. */static u8 safl_pci_bus, safl_pci_devfn;static int safl_devid;#ifdef PCI_SUPPORT_VER2static struct pci_dev *safl_pdev;#endifstatic int safl_open_cnt = 0;	/* #times opened */__initfunc(int safl_scan(void)){    if (pcibios_present()) {	int index;	/*	 * Search for an EBSA-285 board or an IOP board. Stop at	 * first one found.	 */	for (index = 0; index < 8; index++) {	    if (pcibios_find_device (PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21554,				     index, &safl_pci_bus, &safl_pci_devfn)		== PCIBIOS_SUCCESSFUL) {		safl_devid = PCI_DEVICE_ID_DEC_21554;		break;	    }	    if (pcibios_find_device (PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285,				     index, &safl_pci_bus, &safl_pci_devfn)		== PCIBIOS_SUCCESSFUL) {		safl_devid = PCI_DEVICE_ID_DEC_21285;		break;	    }	}	if (index < 8) {#ifdef PCI_SUPPORT_VER2	    safl_pdev = pci_find_slot(safl_pci_bus, safl_pci_devfn);#endif	    misc_register(&safl_dev);	    return 0;	}    }    if (safl_debug)	printk(KERN_INFO "Can't find device.\n");    return -ENODEV;}intinit_module(void){    if (safl_debug)	printk(KERN_INFO "%s", version);    return safl_scan();}/* * Dword read from configuration space of secondary PCI bus. */static unsigned intsconfig_read(int addr){    unsigned int val;    outw(2, csr_ioaddr + 0x12);  /* enable downstream config */    outl(addr | (1<<24), csr_ioaddr + 0x00);    val = inl(csr_ioaddr + 4);    outw(0, csr_ioaddr + 0x12);  /* disable downstream config */    return val;}/* * Dword write to configuration space of secondary PCI bus. */static voidsconfig_write(int addr, int val){    outw(2, csr_ioaddr + 0x12);  /* enable downstream config */    outl(addr | (1<<24), csr_ioaddr + 0x00);    outl(val, csr_ioaddr + 4);    outw(0, csr_ioaddr + 0x12);  /* disable downstream config */}/* * Dword read from configuration space of primary PCI bus. */static unsigned intpconfig_read(int addr){    unsigned int val;#ifdef PCI_SUPPORT_VER2    pci_read_config_dword(safl_pdev, addr, &val);#else    pcibios_read_config_dword(safl_pci_bus, safl_pci_devfn, addr, &val);#endif    return val;}/* * Dword write to configuration space of primary PCI bus. */static voidpconfig_write(int addr, int val){#ifdef PCI_SUPPORT_VER2    pci_write_config_dword(safl_pdev, addr, val);#else    pcibios_write_config_dword(safl_pci_bus, safl_pci_devfn, addr, val);#endif}static intsafl_open( struct inode *inode, struct file *file ){    if (safl_open_cnt) {	if (safl_debug)	    printk(KERN_INFO "SA-Flash already open.\n");	return( -EBUSY );    }    if (safl_devid == PCI_DEVICE_ID_DEC_21554) {	csr_ioaddr = pconfig_read(PCI_BASE_ADDRESS_1) & PCI_BASE_ADDRESS_IO_MASK;	flash_addr = pconfig_read(PCI_BASE_ADDRESS_3) & PCI_BASE_ADDRESS_MEM_MASK;	if (safl_debug) {	    printk(KERN_INFO "IOP: csr_io[%lx].\n", csr_ioaddr);	    printk(KERN_INFO "IOP: flash_add[%lx].\n", flash_addr);	}	/*	 * Need to configure downstream side of 21554.	 * These addresses are pretty arbitrary.	 */	pconfig_write(0x50, 0xf0000000);  /* secondary CSR memory */	pconfig_write(0x54, 0xf201);	  /* secondary CSR I/O    */	pconfig_write(0x58, 0xf401);	  /* Upstream I/O         */	pconfig_write(0x5c, 0xf1000008);  /* Upstream memory 1    */	pconfig_write(0x44, 0x29000017);  /* enable mem an I/O    */	/* set downstream mem2 xlate base */	pconfig_write(0x9c, 0xA0000000);	/* set 21285 ROM address to same */	sconfig_write(0x30, 0xA0000001);	/* set 21285 ROM write byte address */	sconfig_write(0x68, 0);    } else if (safl_devid == PCI_DEVICE_ID_DEC_21285) {	/*	 * I'm not sure how best to handle this. Basically, you want	 * to assign a physical address for the expansion ROM space	 * of the 21285. There doesn't appear to be a good way to	 * find an unused physical space for the PCI bus. This seems	 * to work for the limited number of motherboards that this	 * code has been tested on. YMMV.	 */	flash_addr = 0xb0000000;	pconfig_write(PCI_ROM_ADDRESS, flash_addr | PCI_ROM_ADDRESS_ENABLE);    }    safl_open_cnt++;    MOD_INC_USE_COUNT;    return 0;}static intsafl_close( struct inode *inode, struct file *file ){    safl_open_cnt--;    if (safl_devid == PCI_DEVICE_ID_DEC_21285)	pconfig_write(PCI_ROM_ADDRESS, 0);    if (safl_devid == PCI_DEVICE_ID_DEC_21554)	sconfig_write(0x30, 0);    MOD_DEC_USE_COUNT;    return 0;}static inline unsigned longpgprot_noncached(unsigned long prot){#if LINUX_VERSION_CODE >= 0x020100    if (boot_cpu_data.x86 > 3)	prot |= _PAGE_PCD;#endif    return prot;}static int#if LINUX_VERSION_CODE >= 0x020100safl_mmap(struct file * file, struct vm_area_struct * vma)#elsesafl_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma)#endif{    unsigned long size;    if (vma->vm_offset != 0)	return -EINVAL;    size = vma->vm_end - vma->vm_start;    if (size > FLASH_SZ)	return -EINVAL;    pgprot_val(vma->vm_page_prot) = pgprot_noncached(pgprot_val(vma->vm_page_prot));#if LINUX_VERSION_CODE >= 0x020100    vma->vm_flags |= VM_IO;#endif    if (remap_page_range(vma->vm_start, flash_addr, size, vma->vm_page_prot))	return -EAGAIN;#if LINUX_VERSION_CODE < 0x020100    vma->vm_inode = inode;    inode->i_count++;#endif    return 0;}voidcleanup_module(void){    misc_deregister(&safl_dev);}/* * Local variables: *  compile-command: "cc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c safl.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`" * End: */

⌨️ 快捷键说明

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