Chameleon

Chameleon Svn Source Tree

Root/branches/rewrite/i386/libsaio/pci.c

Source at commit 1066 created 12 years 10 months ago.
By meklort, Removing even more code...
1/*
2 *
3 * Copyright 2008 by Islam M. Ahmed Zaid. All rights reserved.
4 *
5 */
6
7#include "libsaio.h"
8#include "pci.h"
9
10#ifndef DEBUG_PCI
11#define DEBUG_PCI 0
12#endif
13
14#if DEBUG_PCI
15#define DBG(x...)printf(x)
16#else
17#define DBG(x...)
18#endif
19
20pci_dt_t*root_pci_dev;
21
22
23uint8_t pci_config_read8(uint32_t pci_addr, uint8_t reg)
24{
25pci_addr |= reg & ~3;
26outl(PCI_ADDR_REG, pci_addr);
27return inb(PCI_DATA_REG + (reg & 3));
28}
29
30uint16_t pci_config_read16(uint32_t pci_addr, uint8_t reg)
31{
32pci_addr |= reg & ~3;
33outl(PCI_ADDR_REG, pci_addr);
34return inw(PCI_DATA_REG + (reg & 2));
35}
36
37uint32_t pci_config_read32(uint32_t pci_addr, uint8_t reg)
38{
39pci_addr |= reg & ~3;
40outl(PCI_ADDR_REG, pci_addr);
41return inl(PCI_DATA_REG);
42}
43
44void pci_config_write8(uint32_t pci_addr, uint8_t reg, uint8_t data)
45{
46pci_addr |= reg & ~3;
47outl(PCI_ADDR_REG, pci_addr);
48outb(PCI_DATA_REG + (reg & 3), data);
49}
50
51void pci_config_write16(uint32_t pci_addr, uint8_t reg, uint16_t data)
52{
53pci_addr |= reg & ~3;
54outl(PCI_ADDR_REG, pci_addr);
55outw(PCI_DATA_REG + (reg & 2), data);
56}
57
58void pci_config_write32(uint32_t pci_addr, uint8_t reg, uint32_t data)
59{
60pci_addr |= reg & ~3;
61outl(PCI_ADDR_REG, pci_addr);
62outl(PCI_DATA_REG, data);
63}
64
65void scan_pci_bus(pci_dt_t *start, uint8_t bus)
66{
67pci_dt_t*new;
68pci_dt_t**current = &start->children;
69uint32_tid;
70uint32_tpci_addr;
71uint8_tdev;
72uint8_tfunc;
73uint8_tsecondary_bus;
74uint8_theader_type;
75
76for (dev = 0; dev < 32; dev++) {
77for (func = 0; func < 8; func++) {
78pci_addr = PCIADDR(bus, dev, func);
79id = pci_config_read32(pci_addr, PCI_VENDOR_ID);
80if (!id || id == 0xffffffff) {
81continue;
82}
83new = (pci_dt_t*)malloc(sizeof(pci_dt_t));
84bzero(new, sizeof(pci_dt_t));
85new->dev.addr= pci_addr;
86new->vendor_id= id & 0xffff;
87new->device_id= (id >> 16) & 0xffff;
88new->subsys_id.subsys_id= pci_config_read32(pci_addr, PCI_SUBSYSTEM_VENDOR_ID);
89new->class_id= pci_config_read16(pci_addr, PCI_CLASS_DEVICE);
90new->parent= start;
91
92header_type = pci_config_read8(pci_addr, PCI_HEADER_TYPE);
93switch (header_type & 0x7f) {
94case PCI_HEADER_TYPE_BRIDGE:
95case PCI_HEADER_TYPE_CARDBUS:
96secondary_bus = pci_config_read8(pci_addr, PCI_SECONDARY_BUS);
97if (secondary_bus != 0) {
98scan_pci_bus(new, secondary_bus);
99}
100break;
101}
102*current = new;
103current = &new->next;
104
105if ((func == 0) && ((header_type & 0x80) == 0)) {
106break;
107}
108}
109}
110}
111
112void enable_pci_devs(void)
113{
114uint16_t id;
115uint32_t rcba, *fd;
116
117id = pci_config_read16(PCIADDR(0, 0x00, 0), 0x00);
118/* make sure we're on Intel chipset */
119if (id != 0x8086)
120return;
121rcba = pci_config_read32(PCIADDR(0, 0x1f, 0), 0xf0) & ~1;
122fd = (uint32_t *)(rcba + 0x3418);
123/* set SMBus Disable (SD) to 0 */
124*fd &= ~0x8;
125/* and all devices? */
126//*fd = 0x1;
127}
128
129
130void build_pci_dt(void)
131{
132root_pci_dev = malloc(sizeof(pci_dt_t));
133bzero(root_pci_dev, sizeof(pci_dt_t));
134enable_pci_devs();
135scan_pci_bus(root_pci_dev, 0);
136
137#if DEBUG_PCI
138dump_pci_dt(root_pci_dev->children);
139pause();
140#endif
141}
142
143static char dev_path[256];
144char *get_pci_dev_path(pci_dt_t *pci_dt)
145{
146pci_dt_t*current;
147pci_dt_t*end;
148chartmp[64];
149
150dev_path[0] = 0;
151end = root_pci_dev;
152
153int uid = 0; //getPciRootUID();
154while (end != pci_dt)
155{
156current = pci_dt;
157while (current->parent != end)
158current = current->parent;
159end = current;
160if (current->parent == root_pci_dev)
161{
162sprintf(tmp, "PciRoot(0x%x)/Pci(0x%x,0x%x)", uid,
163current->dev.bits.dev, current->dev.bits.func);
164} else {
165sprintf(tmp, "/Pci(0x%x,0x%x)",
166current->dev.bits.dev, current->dev.bits.func);
167}
168strcat(dev_path, tmp);
169}
170return dev_path;
171}
172
173void dump_pci_dt(pci_dt_t *pci_dt)
174{
175pci_dt_t*current;
176
177current = pci_dt;
178while (current) {
179printf("%02x:%02x.%x [%04x] [%04x:%04x] (subsys [%04x:%04x]):: %s\n",
180current->dev.bits.bus, current->dev.bits.dev, current->dev.bits.func,
181current->class_id, current->vendor_id, current->device_id,
182current->subsys_id.subsys.vendor_id, current->subsys_id.subsys.device_id,
183get_pci_dev_path(current));
184dump_pci_dt(current->children);
185current = current->next;
186}
187}
188

Archive Download this file

Revision: 1066