2 meinOS - A unix-like x86 microkernel operating system
3 Copyright (C) 2008 Janosch Gräf <janosch.graef@gmx.net>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <sys/types.h>
26 * Reads dword from config register of PCI device
27 * @param dev PCI device
28 * @param offset Register offset
29 * @return Register content
31 uint32_t pci_config_readd(pcidev_t
*dev
,size_t offset
) {
36 * Writes dword in config register of PCI device
37 * @param dev PCI device
38 * @param offset Register offset
39 * @param val Value to write
41 void pci_config_writed(pcidev_t
*dev
,size_t offset
,uint32_t val
) {
47 * Finds PCI device by VendorID and DeviceID
48 * @param dev Pointer to PCI device
49 * @param vendorid VendorID
50 * @param deviceid DeviceID
51 * @param index If more than 1 device is found, select n'th one
52 * @return Whether device was found
54 int pci_finddev_byids(pcidev_t
*dev
,int vendorid
,int deviceid
,int index
) {
55 for (dev
->bus
=0;dev
->bus
<PCI_MAXBUSSES
;dev
->bus
++) {
56 for (dev
->slot
=0;dev
->slot
<PCI_MAXSLOTS
;dev
->slot
++) {
57 if (pci_get_vendorid(dev
)==vendorid
&& pci_get_deviceid(dev
)==deviceid
) {
67 * Finds PCI device by Classcode and Subclass
68 * @param dev Pointer to PCI device
69 * @param classcode Classcode
70 * @param subclass Subclass
71 * @param index If more than 1 device is found, select n'th one
72 * @return Whether device was found
74 int pci_finddev_byclass(pcidev_t
*dev
,int classcode
,int subclass
,int index
) {
75 for (dev
->bus
=0;dev
->bus
<PCI_MAXBUSSES
;dev
->bus
++) {
76 for (dev
->slot
=0;dev
->slot
<PCI_MAXSLOTS
;dev
->slot
++) {
77 if (pci_get_subclass(dev
)==classcode
&& pci_get_subclass(dev
)==subclass
) {
87 * Returns Pointer to BAR structure
88 * @param dev PCI device
89 * @param barnum Number of BAR register (0..5)
90 * @return Pointer to BAR structure
92 pcibar_t
*pci_getbar(pcidev_t
*dev
,int barnum
) {
93 pcibar_t
*bar
= malloc(sizeof(pcibar_t
));
94 uint32_t bar_value
= pci_config_readd(dev
,barnum
*4+0x10);
95 bar
->type
= bar_value
&1;
96 if (bar
->type
==PCI_BARTYPE_MEMORY
) {
97 bar
->addr
= (void*)(bar_value
&0xFFFFFFF0);
98 pci_config_writed(dev
,barnum
*4+0x10,0xFFFFFFF0|bar
->type
);
99 bar
->size
= pci_config_readd(dev
,barnum
*4+0x10);
100 bar
->size
= (~bar
->size
|0xF)+1;
101 pci_config_writed(dev
,barnum
*4+0x10,bar_value
);
103 else bar
->ioport
= bar_value
&0xFFFFFFFC;