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

📄 bios32.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (dev->vendor == vendor && dev->device == device_id) {	    if (curr == index) {		*devfn = dev->devfn;		*bus = dev->bus->number;		return PCIBIOS_SUCCESSFUL;	    }	    ++curr;	}    }    return PCIBIOS_DEVICE_NOT_FOUND;}/* * Given the class, find the n'th instance of that device * in the system. */static int pci_direct_find_class (unsigned int class_code, unsigned short index,			  unsigned char *bus, unsigned char *devfn){    unsigned int curr = 0;    struct pci_dev *dev;    for (dev = pci_devices; dev; dev = dev->next) {	if (dev->class == class_code) {	    if (curr == index) {		*devfn = dev->devfn;		*bus = dev->bus->number;		return PCIBIOS_SUCCESSFUL;	    }	    ++curr;	}    }    return PCIBIOS_DEVICE_NOT_FOUND;}/* * Functions for accessing PCI configuration space with type 1 accesses */#define CONFIG_CMD(bus, device_fn, where)   (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3))static int pci_conf1_read_config_byte(unsigned char bus, unsigned char device_fn,			       unsigned char where, unsigned char *value){    unsigned long flags;    save_flags(flags); cli();    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);    *value = inb(0xCFC + (where&3));    restore_flags(flags);    return PCIBIOS_SUCCESSFUL;}static int pci_conf1_read_config_word (unsigned char bus,    unsigned char device_fn, unsigned char where, unsigned short *value){    unsigned long flags;    if (where&1) return PCIBIOS_BAD_REGISTER_NUMBER;    save_flags(flags); cli();    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);        *value = inw(0xCFC + (where&2));    restore_flags(flags);    return PCIBIOS_SUCCESSFUL;    }static int pci_conf1_read_config_dword (unsigned char bus, unsigned char device_fn, 				 unsigned char where, unsigned int *value){    unsigned long flags;    if (where&3) return PCIBIOS_BAD_REGISTER_NUMBER;    save_flags(flags); cli();    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);    *value = inl(0xCFC);    restore_flags(flags);    return PCIBIOS_SUCCESSFUL;    }static int pci_conf1_write_config_byte (unsigned char bus, unsigned char device_fn, 				 unsigned char where, unsigned char value){    unsigned long flags;    save_flags(flags); cli();    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);        outb(value, 0xCFC + (where&3));    restore_flags(flags);    return PCIBIOS_SUCCESSFUL;}static int pci_conf1_write_config_word (unsigned char bus, unsigned char device_fn, 				 unsigned char where, unsigned short value){    unsigned long flags;    if (where&1) return PCIBIOS_BAD_REGISTER_NUMBER;    save_flags(flags); cli();    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);    outw(value, 0xCFC + (where&2));    restore_flags(flags);    return PCIBIOS_SUCCESSFUL;}static int pci_conf1_write_config_dword (unsigned char bus, unsigned char device_fn, 				  unsigned char where, unsigned int value){    unsigned long flags;    if (where&3) return PCIBIOS_BAD_REGISTER_NUMBER;    save_flags(flags); cli();    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);    outl(value, 0xCFC);    restore_flags(flags);    return PCIBIOS_SUCCESSFUL;}#undef CONFIG_CMD/* * functiontable for type 1 */static struct pci_access pci_direct_conf1 = {      pci_direct_find_device,      pci_direct_find_class,      pci_conf1_read_config_byte,      pci_conf1_read_config_word,      pci_conf1_read_config_dword,      pci_conf1_write_config_byte,      pci_conf1_write_config_word,      pci_conf1_write_config_dword};/* * Functions for accessing PCI configuration space with type 2 accesses */#define IOADDR(devfn, where)   ((0xC000 | ((devfn & 0x78) << 5)) + where)#define FUNC(devfn)            (((devfn & 7) << 1) | 0xf0)static int pci_conf2_read_config_byte(unsigned char bus, unsigned char device_fn, 			       unsigned char where, unsigned char *value){    unsigned long flags;    if (device_fn & 0x80)	return PCIBIOS_DEVICE_NOT_FOUND;    save_flags(flags); cli();    outb (FUNC(device_fn), 0xCF8);    outb (bus, 0xCFA);    *value = inb(IOADDR(device_fn,where));    outb (0, 0xCF8);    restore_flags(flags);    return PCIBIOS_SUCCESSFUL;}static int pci_conf2_read_config_word (unsigned char bus, unsigned char device_fn, 				unsigned char where, unsigned short *value){    unsigned long flags;    if (device_fn & 0x80)	return PCIBIOS_DEVICE_NOT_FOUND;    save_flags(flags); cli();    outb (FUNC(device_fn), 0xCF8);    outb (bus, 0xCFA);    *value = inw(IOADDR(device_fn,where));    outb (0, 0xCF8);    restore_flags(flags);    return PCIBIOS_SUCCESSFUL;}static int pci_conf2_read_config_dword (unsigned char bus, unsigned char device_fn, 				 unsigned char where, unsigned int *value){    unsigned long flags;    if (device_fn & 0x80)	return PCIBIOS_DEVICE_NOT_FOUND;    save_flags(flags); cli();    outb (FUNC(device_fn), 0xCF8);    outb (bus, 0xCFA);    *value = inl (IOADDR(device_fn,where));        outb (0, 0xCF8);        restore_flags(flags);    return PCIBIOS_SUCCESSFUL;}static int pci_conf2_write_config_byte (unsigned char bus, unsigned char device_fn, 				 unsigned char where, unsigned char value){    unsigned long flags;    save_flags(flags); cli();    outb (FUNC(device_fn), 0xCF8);    outb (bus, 0xCFA);    outb (value, IOADDR(device_fn,where));    outb (0, 0xCF8);        restore_flags(flags);    return PCIBIOS_SUCCESSFUL;}static int pci_conf2_write_config_word (unsigned char bus, unsigned char device_fn, 				 unsigned char where, unsigned short value){    unsigned long flags;    save_flags(flags); cli();    outb (FUNC(device_fn), 0xCF8);    outb (bus, 0xCFA);    outw (value, IOADDR(device_fn,where));    outb (0, 0xCF8);        restore_flags(flags);    return PCIBIOS_SUCCESSFUL;}static int pci_conf2_write_config_dword (unsigned char bus, unsigned char device_fn, 				  unsigned char where, unsigned int value){    unsigned long flags;    save_flags(flags); cli();    outb (FUNC(device_fn), 0xCF8);    outb (bus, 0xCFA);    outl (value, IOADDR(device_fn,where));        outb (0, 0xCF8);        restore_flags(flags);    return PCIBIOS_SUCCESSFUL;}#undef IOADDR#undef FUNC/* * functiontable for type 2 */static struct pci_access pci_direct_conf2 = {      pci_direct_find_device,      pci_direct_find_class,      pci_conf2_read_config_byte,      pci_conf2_read_config_word,      pci_conf2_read_config_dword,      pci_conf2_write_config_byte,      pci_conf2_write_config_word,      pci_conf2_write_config_dword};static struct pci_access *check_direct_pci(void){    unsigned int tmp;    unsigned long flags;    save_flags(flags); cli();    /*     * check if configuration type 1 works     */    outb (0x01, 0xCFB);    tmp = inl (0xCF8);    outl (0x80000000, 0xCF8);    if (inl (0xCF8) == 0x80000000) {	outl (tmp, 0xCF8);	restore_flags(flags);	printk("pcibios_init: Using configuration type 1\n");	return &pci_direct_conf1;    }    outl (tmp, 0xCF8);    /*     * check if configuration type 2 works     */    outb (0x00, 0xCFB);    outb (0x00, 0xCF8);    outb (0x00, 0xCFA);    if (inb (0xCF8) == 0x00 && inb (0xCFB) == 0x00) {	restore_flags(flags);	printk("pcibios_init: Using configuration type 2\n");	return &pci_direct_conf2;    }    restore_flags(flags);    printk("pcibios_init: Not supported chipset for direct PCI access !\n");    return NULL;}/* * access defined pcibios functions via * the function table */int pcibios_present(void){	return access_pci ? 1 : 0;}int pcibios_find_class (unsigned int class_code, unsigned short index,	unsigned char *bus, unsigned char *device_fn){   if (access_pci && access_pci->find_class)      return access_pci->find_class(class_code, index, bus, device_fn);        return PCIBIOS_FUNC_NOT_SUPPORTED;}int pcibios_find_device (unsigned short vendor, unsigned short device_id,	unsigned short index, unsigned char *bus, unsigned char *device_fn){    if (access_pci && access_pci->find_device)      return access_pci->find_device(vendor, device_id, index, bus, device_fn);        return PCIBIOS_FUNC_NOT_SUPPORTED;}int pcibios_read_config_byte (unsigned char bus,	unsigned char device_fn, unsigned char where, unsigned char *value){    if (access_pci && access_pci->read_config_byte)      return access_pci->read_config_byte(bus, device_fn, where, value);        return PCIBIOS_FUNC_NOT_SUPPORTED;}int pcibios_read_config_word (unsigned char bus,	unsigned char device_fn, unsigned char where, unsigned short *value){    if (access_pci && access_pci->read_config_word)      return access_pci->read_config_word(bus, device_fn, where, value);        return PCIBIOS_FUNC_NOT_SUPPORTED;}int pcibios_read_config_dword (unsigned char bus,	unsigned char device_fn, unsigned char where, unsigned int *value){    if (access_pci && access_pci->read_config_dword)      return access_pci->read_config_dword(bus, device_fn, where, value);        return PCIBIOS_FUNC_NOT_SUPPORTED;}int pcibios_write_config_byte (unsigned char bus,	unsigned char device_fn, unsigned char where, unsigned char value){    if (access_pci && access_pci->write_config_byte)      return access_pci->write_config_byte(bus, device_fn, where, value);        return PCIBIOS_FUNC_NOT_SUPPORTED;}int pcibios_write_config_word (unsigned char bus,	unsigned char device_fn, unsigned char where, unsigned short value){    if (access_pci && access_pci->write_config_word)      return access_pci->write_config_word(bus, device_fn, where, value);        return PCIBIOS_FUNC_NOT_SUPPORTED;    }int pcibios_write_config_dword (unsigned char bus,	unsigned char device_fn, unsigned char where, unsigned int value){    if (access_pci && access_pci->write_config_dword)      return access_pci->write_config_dword(bus, device_fn, where, value);        return PCIBIOS_FUNC_NOT_SUPPORTED;}const char *pcibios_strerror (int error){	static char buf[80];	switch (error) {		case PCIBIOS_SUCCESSFUL:			return "SUCCESSFUL";		case PCIBIOS_FUNC_NOT_SUPPORTED:			return "FUNC_NOT_SUPPORTED";		case PCIBIOS_BAD_VENDOR_ID:			return "SUCCESSFUL";		case PCIBIOS_DEVICE_NOT_FOUND:			return "DEVICE_NOT_FOUND";		case PCIBIOS_BAD_REGISTER_NUMBER:			return "BAD_REGISTER_NUMBER";                case PCIBIOS_SET_FAILED:          			return "SET_FAILED";                case PCIBIOS_BUFFER_TOO_SMALL:    			return "BUFFER_TOO_SMALL";		default:			sprintf (buf, "UNKNOWN RETURN 0x%x", error);			return buf;	}}unsigned long pcibios_fixup(unsigned long mem_start, unsigned long mem_end){    return mem_start;}#endifunsigned long pcibios_init(unsigned long memory_start, unsigned long memory_end){#ifdef CONFIG_PCI	union bios32 *check;	unsigned char sum;	int i, length;	/*	 * Follow the standard procedure for locating the BIOS32 Service	 * directory by scanning the permissible address range from	 * 0xe0000 through 0xfffff for a valid BIOS32 structure.	 *	 */	for (check = (union bios32 *) 0xe0000;	     check <= (union bios32 *) 0xffff0;	     ++check) {		if (check->fields.signature != BIOS32_SIGNATURE)			continue;		length = check->fields.length * 16;		if (!length)			continue;		sum = 0;		for (i = 0; i < length ; ++i)			sum += check->chars[i];		if (sum != 0)			continue;		if (check->fields.revision != 0) {			printk("pcibios_init : unsupported revision %d at 0x%p, mail drew@colorado.edu\n",				check->fields.revision, check);			continue;		}		printk ("pcibios_init : BIOS32 Service Directory structure at 0x%p\n", check);		if (!bios32_entry) {			if (check->fields.entry >= 0x100000) {				printk("pcibios_init: entry in high memory, trying direct PCI access\n");				access_pci = check_direct_pci();			} else {				bios32_entry = check->fields.entry;				printk ("pcibios_init : BIOS32 Service Directory entry at 0x%lx\n", bios32_entry);				bios32_indirect.address = bios32_entry;			}		}	}	if (bios32_entry && check_pcibios()) 		access_pci = &pci_bios_access;#endif	return memory_start;}

⌨️ 快捷键说明

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