Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 970