Revision: linuxbios@linuxbios.org--devel/freebios--devel--2.0--patch-51
[coreboot.git] / src / arch / i386 / include / arch / romcc_io.h
1 #ifndef ARCH_ROMCC_IO_H
2 #define ARCH_ROMCC_IO_H 1
3
4 #include <stdint.h>
5
6
7 static inline uint8_t read8(unsigned long addr)
8 {
9         return *((volatile uint8_t *)(addr));
10 }
11
12 static inline uint16_t read16(unsigned long addr)
13 {
14         return *((volatile uint16_t *)(addr));
15 }
16
17 static inline uint32_t read32(unsigned long addr)
18 {
19         return *((volatile uint32_t *)(addr));
20 }
21
22 static inline void write8(unsigned long addr, uint8_t value)
23 {
24         *((volatile uint8_t *)(addr)) = value;
25 }
26
27 static inline void write16(unsigned long addr, uint16_t value)
28 {
29         *((volatile uint16_t *)(addr)) = value;
30 }
31
32 static inline void write32(unsigned long addr, uint32_t value)
33 {
34         *((volatile uint32_t *)(addr)) = value;
35 }
36 #if 0
37 typedef __builtin_div_t div_t;
38 typedef __builtin_ldiv_t ldiv_t;
39 typedef __builtin_udiv_t udiv_t;
40 typedef __builtin_uldiv_t uldiv_t;
41
42 static inline div_t div(int numer, int denom)
43 {
44         return __builtin_div(numer, denom);
45 }
46
47 static inline ldiv_t ldiv(long numer, long denom)
48 {
49         return __builtin_ldiv(numer, denom);
50 }
51
52 static inline udiv_t udiv(unsigned numer, unsigned denom)
53 {
54         return __builtin_udiv(numer, denom);
55 }
56
57 static inline uldiv_t uldiv(unsigned long numer, unsigned long denom)
58 {
59         return __builtin_uldiv(numer, denom);
60 }
61
62
63
64 inline int log2(int value)
65 {
66         /* __builtin_bsr is a exactly equivalent to the x86 machine
67          * instruction with the exception that it returns -1  
68          * when the value presented to it is zero.
69          * Otherwise __builtin_bsr returns the zero based index of
70          * the highest bit set.
71          */
72         return __builtin_bsr(value);
73 }
74 #endif
75
76 static inline int log2(int value)
77 {
78         unsigned int r = 0;
79         __asm__ volatile (
80                 "bsrl %1, %0\n\t"
81                 "jnz 1f\n\t"
82                 "movl $-1, %0\n\t"
83                 "1:\n\t"
84                 : "=r" (r) : "r" (value));
85         return r;
86
87 }
88 static inline int log2f(int value)
89 {
90         unsigned int r = 0;
91         __asm__ volatile (
92                 "bsfl %1, %0\n\t"
93                 "jnz 1f\n\t"
94                 "movl $-1, %0\n\t"
95                 "1:\n\t"
96                 : "=r" (r) : "r" (value));
97         return r;
98
99 }
100
101 #define PCI_ADDR(BUS, DEV, FN, WHERE) ( \
102         (((BUS) & 0xFF) << 16) | \
103         (((DEV) & 0x1f) << 11) | \
104         (((FN) & 0x07) << 8) | \
105         ((WHERE) & 0xFF))
106
107 #define PCI_DEV(BUS, DEV, FN) ( \
108         (((BUS) & 0xFF) << 16) | \
109         (((DEV) & 0x1f) << 11) | \
110         (((FN)  & 0x7) << 8))
111
112 #define PCI_ID(VENDOR_ID, DEVICE_ID) \
113         ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
114
115
116 #define PNP_DEV(PORT, FUNC) (((PORT) << 8) | (FUNC))
117
118 typedef unsigned device_t;
119
120 static inline uint8_t pci_read_config8(device_t dev, unsigned where)
121 {
122         unsigned addr;
123         addr = dev | where;
124         outl(0x80000000 | (addr & ~3), 0xCF8);
125         return inb(0xCFC + (addr & 3));
126 }
127
128 static inline uint16_t pci_read_config16(device_t dev, unsigned where)
129 {
130         unsigned addr;
131         addr = dev | where;
132         outl(0x80000000 | (addr & ~3), 0xCF8);
133         return inw(0xCFC + (addr & 2));
134 }
135
136 static inline uint32_t pci_read_config32(device_t dev, unsigned where)
137 {
138         unsigned addr;
139         addr = dev | where;
140         outl(0x80000000 | (addr & ~3), 0xCF8);
141         return inl(0xCFC);
142 }
143
144 static inline void pci_write_config8(device_t dev, unsigned where, uint8_t value)
145 {
146         unsigned addr;
147         addr = dev | where;
148         outl(0x80000000 | (addr & ~3), 0xCF8);
149         outb(value, 0xCFC + (addr & 3));
150 }
151
152 static inline void pci_write_config16(device_t dev, unsigned where, uint16_t value)
153 {
154         unsigned addr;
155         addr = dev | where;
156         outl(0x80000000 | (addr & ~3), 0xCF8);
157         outw(value, 0xCFC + (addr & 2));
158 }
159
160 static inline void pci_write_config32(device_t dev, unsigned where, uint32_t value)
161 {
162         unsigned addr;
163         addr = dev | where;
164         outl(0x80000000 | (addr & ~3), 0xCF8);
165         outl(value, 0xCFC);
166 }
167
168 #define PCI_DEV_INVALID (0xffffffffU)
169 static device_t pci_locate_device(unsigned pci_id, device_t dev)
170 {
171         for(; dev <= PCI_DEV(255, 31, 7); dev += PCI_DEV(0,0,1)) {
172                 unsigned int id;
173                 id = pci_read_config32(dev, 0);
174                 if (id == pci_id) {
175                         return dev;
176                 }
177         }
178         return PCI_DEV_INVALID;
179 }
180
181
182 /* Generic functions for pnp devices */
183 static inline void pnp_write_config(device_t dev, uint8_t reg, uint8_t value)
184 {
185         unsigned port = dev >> 8;
186         outb(reg, port );
187         outb(value, port +1);
188 }
189
190 static inline uint8_t pnp_read_config(device_t dev, uint8_t reg)
191 {
192         unsigned port = dev >> 8;
193         outb(reg, port);
194         return inb(port +1);
195 }
196
197 static inline void pnp_set_logical_device(device_t dev)
198 {
199         unsigned device = dev & 0xff;
200         pnp_write_config(dev, 0x07, device);
201 }
202
203 static inline void pnp_set_enable(device_t dev, int enable)
204 {
205         pnp_write_config(dev, 0x30, enable?0x1:0x0);
206 }
207
208 static inline int pnp_read_enable(device_t dev)
209 {
210         return !!pnp_read_config(dev, 0x30);
211 }
212
213 static inline void pnp_set_iobase(device_t dev, unsigned index, unsigned iobase)
214 {
215         pnp_write_config(dev, index + 0, (iobase >> 8) & 0xff);
216         pnp_write_config(dev, index + 1, iobase & 0xff);
217 }
218
219 static inline uint16_t pnp_read_iobase(device_t dev, unsigned index)
220 {
221         return (uint16_t)((pnp_read_config(dev, index) << 8) | pnp_read_config(dev, index + 1));
222 }
223
224 static inline void pnp_set_irq(device_t dev, unsigned index, unsigned irq)
225 {
226         pnp_write_config(dev, index, irq);
227 }
228
229 static inline void pnp_set_drq(device_t dev, unsigned index, unsigned drq)
230 {
231         pnp_write_config(dev, index, drq & 0xff);
232 }
233
234 #endif /* ARCH_ROMCC_IO_H */