Move all of the files in include/libc/... down to the top level include path.
[newos.git] / apps / window_server / pci.cpp
blob562b192aa2ad358cd6b3594fee17c3df95754fc4
1 /* $Id$
2 **
3 ** Copyright 1999 Brian J. Swetland. All rights reserved.
4 ** Distributed under the terms of the OpenBLT License
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <fcntl.h>
11 #include <i386/io.h>
13 #include "pci.h"
15 typedef struct
17 uchar reg:8;
18 uchar func:3;
19 uchar dev:5;
20 uchar bus:8;
21 uchar rsvd:7;
22 uchar enable:1;
23 } confadd;
25 uint32 pci_read(int bus, int dev, int func, int reg, int bytes)
27 uint32 base;
29 union {
30 confadd c;
31 uint32 n;
32 } u;
34 u.c.enable = 1;
35 u.c.rsvd = 0;
36 u.c.bus = bus;
37 u.c.dev = dev;
38 u.c.func = func;
39 u.c.reg = reg & 0xFC;
41 outl(u.n,0xCF8);
43 base = 0xCFC + (reg & 0x03);
45 switch(bytes){
46 case 1: return inb(base);
47 case 2: return inw(base);
48 case 4: return inl(base);
49 default: return 0;
53 void pci_write(int bus, int dev, int func, int reg, uint32 v, int bytes)
55 uint32 base;
57 union {
58 confadd c;
59 uint32 n;
60 } u;
62 u.c.enable = 1;
63 u.c.rsvd = 0;
64 u.c.bus = bus;
65 u.c.dev = dev;
66 u.c.func = func;
67 u.c.reg = reg & 0xFC;
69 base = 0xCFC + (reg & 0x03);
70 outl(u.n,0xCF8);
71 switch(bytes){
72 case 1: outb(v,base); break;
73 case 2: outw(v,base); break;
74 case 4: outl(v,base); break;
79 int pci_probe(int bus, int dev, int func, pci_cfg *cfg)
81 uint32 *word = (uint32 *) cfg;
82 uint32 v;
83 int i;
84 for(i=0;i<4;i++){
85 word[i] = pci_read(bus,dev,func,4*i,4);
87 if(cfg->vendor_id == 0xffff) return 1;
89 cfg->bus = bus;
90 cfg->dev = dev;
91 cfg->func = func;
92 #if 0
93 printf("Device Info: /bus/pci/%d/%d/%d\n",bus,dev,func);
94 printf(" * Vendor: %S Device: %S Class/SubClass/Interface %X/%X/%X\n",
95 cfg->vendor_id,cfg->device_id,cfg->base_class,cfg->sub_class,cfg->interface);
96 printf(" * Status: %S Command: %S BIST/Type/Lat/CLS: %X/%X/%X/%X\n",
97 cfg->status, cfg->command, cfg->bist, cfg->header_type,
98 cfg->latency_timer, cfg->cache_line_size);
99 #endif
101 switch(cfg->header_type & 0x7F){
102 case 0: /* normal device */
103 for(i=0;i<6;i++){
104 v = pci_read(bus,dev,func,i*4 + 0x10, 4);
105 if(v) {
106 int v2;
107 pci_write(bus,dev,func,i*4 + 0x10, 0xffffffff, 4);
108 v2 = pci_read(bus,dev,func,i*4+0x10, 4) & 0xfffffff0;
109 pci_write(bus,dev,func,i*4 + 0x10, v, 4);
110 v2 = 1 + ~v2;
111 if(v & 1) {
112 // printf(" * Base Register %d IO: %x (%x)\n",i,v&0xfff0,v2&0xffff);
113 cfg->base[i] = v & 0xffff;
114 cfg->size[i] = v2 & 0xffff;
115 } else {
116 // printf(" * Base Register %d MM: %x (%x)\n",i,v&0xfffffff0,v2);
117 cfg->base[i] = v;
118 cfg->size[i] = v2;
120 } else {
121 cfg->base[i] = 0;
122 cfg->size[i] = 0;
126 v = pci_read(bus,dev,func,0x3c,1);
127 // if((v != 0xff) && (v != 0)) printf(" * Interrupt Line: %X\n",v);
128 break;
129 case 1:
130 // printf(" * PCI <-> PCI Bridge\n");
131 break;
132 default:
133 // printf(" * Unknown Header Type\n");
136 return 0;
139 int pci_find(pci_cfg *cfg, uint16 vendor_id, uint16 device_id)
141 int bus,dev,func;
143 for(bus=0;bus<255;bus++){
144 for(dev=0;dev<32;dev++) {
145 if(pci_probe(bus,dev,0,cfg)) continue;
146 if((cfg->vendor_id == vendor_id) &&
147 (cfg->device_id == device_id)) return 0;
148 if(cfg->header_type & 0x80){
149 for(func=1;func<8;func++){
150 if(!pci_probe(bus,dev,func,cfg) &&
151 (cfg->vendor_id == vendor_id) &&
152 (cfg->device_id == device_id)) return 0;