📄 pcibios.c
字号:
/* $Id: pcibios.c,v 1.2 2003/05/21 10:17:24 pefo Exp $ *//* * Copyright (c) 2002 Opsycon AB (www.opsycon.se) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Opsycon AB, Sweden. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */#include <stdio.h>#include <dev/pci/pcivar.h>#include "pcibios.h"intpcibios_find_pci_device ( u_int16_t VendorID, u_int16_t DeviceID, u_int16_t Index, u_int8_t *bus, u_int8_t *device_fn){ u_int16_t vendid, devid; u_int8_t Bus, device; if (VendorID == 0xffff) return PCIBIOS_BAD_VENDOR_ID; for (Bus = 0; Bus <= 255; Bus++) { for (device = 0; device <= 31; device++) { /* If no device there, we'll hit the continue */ if ((pcibios_read_config_word (Bus, device<<3, 0x0, &vendid) != PCIBIOS_SUCCESSFUL) || (vendid != VendorID)) continue; if ((pcibios_read_config_word (Bus, device<<3, 0x2, &devid) != PCIBIOS_SUCCESSFUL) || (devid != DeviceID)) continue; /* If we've gotten this far we've found a match */ if (Index-- != 0) continue; *bus = Bus; *device_fn = device<<3; return PCIBIOS_SUCCESSFUL; } } /* If we haven't returned by this point, no match was found */ return PCIBIOS_DEVICE_NOT_FOUND;}intpcibios_find_pci_class_code ( u_int32_t ClassCode, u_int16_t Index, u_int8_t *bus, u_int8_t *device_fn){ u_int16_t vendid; u_int8_t Bus, device; u_int8_t dev_class; for (Bus = 0; Bus <= 255; Bus++) { for (device = 0; device <= 31; device++) { /* If no device there, we'll hit the continue */ if ((pcibios_read_config_word (Bus, device<<3, 0x0, &vendid) != PCIBIOS_SUCCESSFUL) || (vendid == 0xffff) || (pcibios_read_config_byte (Bus, device<<3, 0xb, &dev_class) != PCIBIOS_SUCCESSFUL) || (dev_class != ClassCode)) continue; /* If we've gotten this far we've found a match */ if (Index-- != 0) continue; *bus = Bus; *device_fn = device<<3; return PCIBIOS_SUCCESSFUL; } } /* If we haven't returned by this point, no match was found */ return PCIBIOS_DEVICE_NOT_FOUND;}intpcibios_read_config_byte ( u_int8_t bus, u_int8_t device_fn, u_int8_t where, u_int8_t *value){ u_int32_t tag; tag = (bus << 16) + (device_fn << 8); *value = (u_int8_t) ((_pci_conf_read(tag, where & ~0x3) >> ((where % 0x4) * 8)) & 0xff); return PCIBIOS_SUCCESSFUL;}intpcibios_read_config_word ( u_int8_t bus, u_int8_t device_fn, u_int8_t where, u_int16_t *value){ u_int32_t tag; if (where & 0x01) return PCIBIOS_BAD_REGISTER_NUMBER; tag = (bus << 16) + (device_fn << 8); *value = (u_int16_t) ((_pci_conf_read(tag, where & ~0x3) >> ((where % 0x4) * 8)) & 0xffff); return PCIBIOS_SUCCESSFUL;}intpcibios_read_config_dword ( u_int8_t bus, u_int8_t device_fn, u_int8_t where, u_int32_t *value){ u_int32_t tag; if (where & 0x03) return PCIBIOS_BAD_REGISTER_NUMBER; tag = (bus << 16) + (device_fn << 8); *value = _pci_conf_read(tag, where); return PCIBIOS_SUCCESSFUL;}intpcibios_write_config_byte ( u_int8_t bus, u_int8_t device_fn, u_int8_t where, u_int8_t value){ u_int32_t tag, old_value; tag = (bus << 16) + (device_fn << 8); /* get original value */ old_value = _pci_conf_read(tag, where & ~0x3); /* mask out the desired byte */ old_value &= (~(0x000000ff << ((where % 0x4) * 8))); /* or in the new byte */ old_value |= (((u_int32_t)value) << ((where % 4) * 8)); _pci_conf_write(tag, where & ~0x3, old_value); return PCIBIOS_SUCCESSFUL;}intpcibios_write_config_word ( u_int8_t bus, u_int8_t device_fn, u_int8_t where, u_int16_t value){ u_int32_t tag, old_value; if (where & 0x01) return PCIBIOS_BAD_REGISTER_NUMBER; tag = (bus << 16) + (device_fn << 8); /* get original value */ old_value = _pci_conf_read(tag, where & ~0x3); /* mask out the desired word */ old_value &= (~(0x0000ffff << ((where % 0x2) * 8))); /* or in the new word */ old_value |= (((u_int32_t)value) << ((where % 4) * 8)); _pci_conf_write(tag, where & ~0x3, old_value); return PCIBIOS_SUCCESSFUL;}intpcibios_write_config_dword ( u_int8_t bus, u_int8_t device_fn, u_int8_t where, u_int32_t value){ u_int32_t tag; if (where & 0x03) return PCIBIOS_BAD_REGISTER_NUMBER; tag = (bus << 16) + (device_fn << 8); _pci_conf_write(tag, where, value); return PCIBIOS_SUCCESSFUL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -