df6604e08e1289a784d6a5ba27bea81db718f0f7
[coreboot.git] / src / arch / i386 / include / arch / intel.h
1 /*
2 This software and ancillary information (herein called SOFTWARE )
3 called LinuxBIOS          is made available under the terms described
4 here.  The SOFTWARE has been approved for release with associated
5 LA-CC Number 00-34   .  Unless otherwise indicated, this SOFTWARE has
6 been authored by an employee or employees of the University of
7 California, operator of the Los Alamos National Laboratory under
8 Contract No. W-7405-ENG-36 with the U.S. Department of Energy.  The
9 U.S. Government has rights to use, reproduce, and distribute this
10 SOFTWARE.  The public may copy, distribute, prepare derivative works
11 and publicly display this SOFTWARE without charge, provided that this
12 Notice and any statement of authorship are reproduced on all copies.
13 Neither the Government nor the University makes any warranty, express
14 or implied, or assumes any liability or responsibility for the use of
15 this SOFTWARE.  If SOFTWARE is modified to produce derivative works,
16 such modified SOFTWARE should be clearly marked, so as not to confuse
17 it with the version available from LANL.
18  */
19 /* Copyright 2000, Ron Minnich, Advanced Computing Lab, LANL
20  * rminnich@lanl.gov
21  */
22
23
24 #ifndef ROM_INTEL_H
25 #define ROM_INTEL_H
26
27 /*
28  * Bootstrap code for the Intel
29  *
30  * $Id$
31  *
32  */
33
34 /* 
35  *      Config registers. 
36  */
37 /* yeah, yeah, I know these are macros, which is bad. Don't forget: 
38  * we have almost no assembly, so I am not worrying just yet about this. 
39  * we'll fix it someday if we care. My guess is we won't.
40  */
41
42 /* well we want functions. But first we want to see it work at all. */
43 #undef FUNCTIONS
44 #ifndef FUNCTIONS
45
46
47 #define RET_LABEL(label)        \
48         jmp label##_done
49
50 #define CALL_LABEL(label)       \
51         jmp label               ;\
52 label##_done:
53
54 #define CALLSP(func) \
55         lea     0f, %esp        ; \
56         jmp func                ; \
57 0:
58
59 #define RETSP \
60         jmp *%esp
61
62
63 #define DELAY(x) mov x, %ecx ;\
64         1: loop 1b ;\
65
66
67         /*
68          * Macro:       PCI_WRITE_CONFIG_BYTE
69          * Arguments:   %eax address to write to (includes bus, device, function, &offset)
70          *              %dl byte to write
71          *
72          * Results:     none
73          *
74          * Trashed:     %eax, %edx
75          * Effects:     writes a single byte to pci config space
76          *
77          * Notes:       This routine is optimized for minimal register usage.
78          *              And the tricks it does cannot scale beyond writing a single byte.
79          *               
80          *              What it does is almost simple.
81          *              It preserves %eax (baring special bits) until it is written
82          *              out to the appropriate port.  And hides the data byte
83          *              in the high half of edx.
84          *
85          *              In %edx[3] it stores the byte to write.
86          *              In %edx[2] it stores the lower three bits of the address.
87          */
88
89
90 #define PCI_WRITE_CONFIG_BYTE \
91         shll $8,   %edx         ; \
92         movb %al,  %dl          ; \
93         andb $0x3, %dl          ; \
94         shll $16,  %edx         ; \
95         \
96         orl  $0x80000000, %eax  ; \
97         andl $0xfffffffc, %eax  ; \
98         movw $0xcf8, %dx        ; \
99         outl %eax,  %dx         ; \
100         \
101         shrl $16,  %edx         ; \
102         movb %dh,  %al          ; \
103         movb $0,   %dh          ; \
104         addl $0xcfc, %edx       ; \
105         outb %al,  %dx
106
107
108         /*
109          * Macro:       PCI_WRITE_CONFIG_WORD
110          * Arguments:   %eax address to write to (includes bus, device, function, &offset)
111          *              %ecx word to write
112          *
113          * Results:     none
114          *
115          * Trashed:     %eax, %edx
116          * Preserved:   %ecx
117          * Effects:     writes a single byte to pci config space
118          *
119          * Notes:       This routine is optimized for minimal register usage.
120          *               
121          *              What it does is almost simple.
122          *              It preserves %eax (baring special bits) until it is written
123          *              out to the appropriate port.  And hides the least significant
124          *              bits of the address in the high half of edx.
125          *
126          *              In %edx[2] it stores the lower three bits of the address.
127          */
128
129
130 #define PCI_WRITE_CONFIG_WORD \
131         movb %al,  %dl          ; \
132         andl $0x3, %edx         ; \
133         shll $16,  %edx         ; \
134         \
135         orl  $0x80000000, %eax  ; \
136         andl $0xfffffffc, %eax  ; \
137         movw $0xcf8, %dx        ; \
138         outl %eax,  %dx         ; \
139         \
140         shrl $16,  %edx         ; \
141         movl %ecx, %eax         ; \
142         addl $0xcfc, %edx       ; \
143         outw %ax,  %dx
144
145
146
147         /*
148          * Macro:       PCI_WRITE_CONFIG_DWORD
149          * Arguments:   %eax address to write to (includes bus, device, function, &offset)
150          *              %ecx dword to write
151          *
152          * Results:     none
153          *
154          * Trashed:     %eax, %edx
155          * Preserved:   %ecx
156          * Effects:     writes a single byte to pci config space
157          *
158          * Notes:       This routine is optimized for minimal register usage.
159          *               
160          *              What it does is almost simple.
161          *              It preserves %eax (baring special bits) until it is written
162          *              out to the appropriate port.  And hides the least significant
163          *              bits of the address in the high half of edx.
164          *
165          *              In %edx[2] it stores the lower three bits of the address.
166          */
167
168
169 #define PCI_WRITE_CONFIG_DWORD \
170         movb %al,  %dl          ; \
171         andl $0x3, %edx         ; \
172         shll $16,  %edx         ; \
173         \
174         orl  $0x80000000, %eax  ; \
175         andl $0xfffffffc, %eax  ; \
176         movw $0xcf8, %dx        ; \
177         outl %eax,  %dx         ; \
178         \
179         shrl $16,  %edx         ; \
180         movl %ecx, %eax         ; \
181         addl $0xcfc, %edx       ; \
182         outl %eax,  %dx
183
184
185
186         
187         /*
188          * Macro:       PCI_READ_CONFIG_BYTE
189          * Arguments:   %eax address to read from (includes bus, device, function, &offset)
190          *
191          * Results:     %al Byte read
192          *
193          * Trashed:     %eax, %edx
194          * Effects:     reads a single byte from pci config space
195          *
196          * Notes:       This routine is optimized for minimal register usage.
197          *               
198          *              What it does is almost simple.
199          *              It preserves %eax (baring special bits) until it is written
200          *              out to the appropriate port.  And hides the least significant
201          *              bits of the address in the high half of edx.
202          *
203          *              In %edx[2] it stores the lower three bits of the address.
204          */
205
206
207 #define PCI_READ_CONFIG_BYTE \
208         movb %al,  %dl          ; \
209         andl $0x3, %edx         ; \
210         shll $16,  %edx         ; \
211         \
212         orl  $0x80000000, %eax  ; \
213         andl $0xfffffffc, %eax  ; \
214         movw $0xcf8, %dx        ; \
215         outl %eax,  %dx         ; \
216         \
217         shrl $16,  %edx         ; \
218         addl $0xcfc, %edx       ; \
219         inb  %dx,  %al
220
221
222
223         /*
224          * Macro:       PCI_READ_CONFIG_WORD
225          * Arguments:   %eax address to read from (includes bus, device, function, &offset)
226          *
227          * Results:     %ax word read
228          *
229          * Trashed:     %eax, %edx
230          * Effects:     reads a 2 bytes from pci config space
231          *
232          * Notes:       This routine is optimized for minimal register usage.
233          *               
234          *              What it does is almost simple.
235          *              It preserves %eax (baring special bits) until it is written
236          *              out to the appropriate port.  And hides the least significant
237          *              bits of the address in the high half of edx.
238          *
239          *              In %edx[2] it stores the lower three bits of the address.
240          */
241
242
243 #define PCI_READ_CONFIG_WORD \
244         movb %al,  %dl          ; \
245         andl $0x3, %edx         ; \
246         shll $16,  %edx         ; \
247         \
248         orl  $0x80000000, %eax  ; \
249         andl $0xfffffffc, %eax  ; \
250         movw $0xcf8, %dx        ; \
251         outl %eax,  %dx         ; \
252         \
253         shrl $16,  %edx         ; \
254         addl $0xcfc, %edx       ; \
255         inw  %dx,  %ax
256
257
258
259         /*
260          * Macro:       PCI_READ_CONFIG_DWORD
261          * Arguments:   %eax address to read from (includes bus, device, function, &offset)
262          *
263          * Results:     %eax
264          *
265          * Trashed:     %edx
266          * Effects:     reads 4 bytes from pci config space
267          *
268          * Notes:       This routine is optimized for minimal register usage.
269          *               
270          *              What it does is almost simple.
271          *              It preserves %eax (baring special bits) until it is written
272          *              out to the appropriate port.  And hides the least significant
273          *              bits of the address in the high half of edx.
274          *
275          *              In %edx[2] it stores the lower three bits of the address.
276          */
277
278
279 #define PCI_READ_CONFIG_DWORD \
280         movb %al,  %dl          ; \
281         andl $0x3, %edx         ; \
282         shll $16,  %edx         ; \
283         \
284         orl  $0x80000000, %eax  ; \
285         andl $0xfffffffc, %eax  ; \
286         movw $0xcf8, %dx        ; \
287         outl %eax,  %dx         ; \
288         \
289         shrl $16,  %edx         ; \
290         addl $0xcfc, %edx       ; \
291         inl  %dx,  %eax
292
293
294
295
296 #define CS_READ(which)  \
297                  mov  $0x80000000,%eax ; \
298                  mov  which,%ax ; \
299                  and  $0xfc,%al            /* clear bits 1-0 */ ; \
300                  mov  $0xcf8,%dx           /* port 0xcf8 ?*/ ; \
301                  outl  %eax,%dx             /* open up CS config */ ; \
302                  add  $0x4,%dl             /* 0xcfc data port 0 */ ; \
303                  mov  which,%al ; \
304                  and  $0x3,%al             /* only bits 1-0 */ ; \
305                  add  %al,%dl ; \
306                  inb   %dx,%al              /* read  */ ; \
307
308
309 #define CS_WRITE(which, data)  \
310                  mov  $0x80000000,%eax       /* 32bit word with bit 31 set */ ; \
311                  mov  which,%ax             /* put the reg# in the low part */ ; \
312                  and  $0xfc,%al             /* dword align the reg# */ ; \
313                  mov  $0xcf8,%dx            /* enable port  */ ; \
314                  outl  %eax,%dx ; \
315                  add  $0x4,%dl             /* 1st data port */ ; \
316                  mov  which,%ax             /* register# */ ; \
317                  and  $0x3,%ax ; \
318                  add  %al,%dl ; \
319                  mov  data, %al ; \
320                  outb  %al,%dx                /* write to reg */ 
321
322 #define REGBIS(which, bis) \
323         CS_READ(which) ;\
324         movb bis, %cl ;\
325         orb %al, %cl ;\
326         CS_WRITE(which, %cl)
327
328 #define REGBIC(which, bic) \
329         CS_READ(which) ;\
330         movb bic, %cl ;\
331         notb %cl ;\
332         andb %al, %cl ;\
333         CS_WRITE(which, %cl)
334
335
336 /* macro to BIC and BIS a reg. calls read a reg,
337  * does a BIC and then a BIS on it.
338  * to clear no bits, make BIC 0.
339  * to set no bits, make BIS 0
340  */
341 #define REGBICBIS(which, bic, bis) \
342         CS_READ(which) ;\
343         movb bic, %cl ;\
344         notb %cl ;\
345         andb %cl, %al ;\
346         movb bis, %cl ;\
347         orb %al, %cl ;\
348         CS_WRITE(which, %cl)
349
350 #else
351 NO FUNCTIONS YET!
352 #endif
353
354
355
356 /* originally this macro was from STPC BIOS */
357 #define intel_chip_post_macro(value)                     \
358         movb    $value, %al                             ; \
359         outb    %al, $0x80
360
361 #define INTEL_PDATA_MAGIC 0xdeadbeef
362
363 /* SLOW_DOWN_IO is a delay we can use that is roughly cpu neutral,
364  * and can be used before memory or timer chips come up.
365  * Since this hits the isa bus it's roughly
366  */
367 #define SLOW_DOWN_IO inb $0x80, %al
368
369 #endif /* ROM_INTEL_H */