The Pedigree Project  0.1
Pci.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "pedigree/kernel/machine/Pci.h"
21 #include "pedigree/kernel/Log.h"
22 #include "pedigree/kernel/machine/Device.h"
23 #include "pedigree/kernel/processor/IoPort.h"
24 #include "pedigree/kernel/processor/types.h"
25 #include "pedigree/kernel/utilities/utility.h"
26 
27 #define CONFIG_ADDRESS 0
28 #define CONFIG_DATA 4
29 
30 #define MAX_BUS 4
31 
32 static IoPort configSpace("PCI config space");
33 
34 union ConfigAddress
35 {
36  struct
37  {
38  uint32_t always0 : 2;
39  uint32_t offset : 6;
40  uint32_t function : 3;
41  uint32_t device : 5;
42  uint32_t bus : 8;
43  uint32_t reserved : 7;
44  uint32_t enable : 1;
45  } __attribute__((packed));
46  uint32_t raw;
47 };
48 
49 PciBus PciBus::m_Instance;
50 
51 PciBus::PciBus()
52 {
53 }
54 
55 PciBus::~PciBus()
56 {
57 }
58 
60 {
61  if (!configSpace.allocate(0xCF8, 8))
62  {
63  ERROR("PCI: Config space - unable to allocate IO port!");
64  return;
65  }
66 
67  configSpace.write32(0x80000000, CONFIG_ADDRESS);
68  if (configSpace.read32(CONFIG_ADDRESS) != 0x80000000)
69  {
70  ERROR("PCI: Controller not detected.");
71  return;
72  }
73 }
74 
75 uint32_t PciBus::readConfigSpace(Device *pDev, uint8_t offset)
76 {
77  ConfigAddress addr;
78  ByteSet(&addr, 0, sizeof(addr));
79  addr.offset = offset;
80  addr.function = pDev->getPciFunctionNumber();
81  addr.device = pDev->getPciDevicePosition();
82  addr.bus = pDev->getPciBusPosition();
83  addr.enable = 1;
84 
85  configSpace.write32(addr.raw, CONFIG_ADDRESS);
86  return configSpace.read32(CONFIG_DATA);
87 }
88 
90  uint8_t bus, uint8_t device, uint8_t function, uint8_t offset)
91 {
92  ConfigAddress addr;
93  ByteSet(&addr, 0, sizeof(addr));
94  addr.offset = offset;
95  addr.function = function;
96  addr.device = device;
97  addr.bus = bus;
98  addr.enable = 1;
99 
100  configSpace.write32(addr.raw, CONFIG_ADDRESS);
101  return configSpace.read32(CONFIG_DATA);
102 }
103 
104 void PciBus::writeConfigSpace(Device *pDev, uint8_t offset, uint32_t data)
105 {
106  ConfigAddress addr;
107  ByteSet(&addr, 0, sizeof(addr));
108  addr.offset = offset;
109  addr.function = pDev->getPciFunctionNumber();
110  addr.device = pDev->getPciDevicePosition();
111  addr.bus = pDev->getPciBusPosition();
112  addr.enable = 1;
113 
114  configSpace.write32(addr.raw, CONFIG_ADDRESS);
115  configSpace.write32(data, CONFIG_DATA);
116 }
117 
119  uint8_t bus, uint8_t device, uint8_t function, uint8_t offset,
120  uint32_t data)
121 {
122  ConfigAddress addr;
123  ByteSet(&addr, 0, sizeof(addr));
124  addr.offset = offset;
125  addr.function = function;
126  addr.device = device;
127  addr.bus = bus;
128  addr.enable = 1;
129 
130  configSpace.write32(addr.raw, CONFIG_ADDRESS);
131  configSpace.write32(data, CONFIG_DATA);
132 }
uint32_t getPciDevicePosition()
Definition: Device.h:239
uint32_t getPciBusPosition()
Definition: Device.h:234
void initialise()
Definition: Pci.cc:59
Definition: Device.h:43
virtual void write32(uint32_t value, size_t offset=0)
uint32_t getPciFunctionNumber()
Definition: Device.h:244
I/O port range.
Definition: IoPort.h:34
uint32_t readConfigSpace(Device *pDev, uint8_t offset)
Definition: Pci.cc:75
bool allocate(io_port_t ioPort, size_t size)
Definition: IoPort.cc:34
#define ERROR(text)
Definition: Log.h:82
Definition: Pci.h:29
virtual uint32_t read32(size_t offset=0)
void writeConfigSpace(Device *pDev, uint8_t offset, uint32_t data)
Definition: Pci.cc:104