source: rtems/c/src/lib/libbsp/i386/shared/pci/pcibios.c @ 196094eb

4.104.114.84.95
Last change on this file since 196094eb was 0ebbf66, checked in by Joel Sherrill <joel.sherrill@…>, on 10/05/98 at 22:36:06

Large patch from Erik Ivanenko <erik.ivanenko@…> which
moves pieces of the pc386 bsp up to a shared level for all i386 BSPs
and modifies the i386ex BSP to use those shared pieces. Serial remote
debugging is included for both targets. Erik's notes:

There are several workarounds in it:

1) #define NEXT_GAS is hardcoded in pc386/start/start.s
2) #define NEXT_GAS is hardcoded in i386ex/start/start.s
3) #define NEW_GAS is hardcoded in pc386/start16.s
4) #undef assert and redeclare _assert hardcoded in console.c for

both pc386 and i386ex due to my egcs1.1b ~ newlib problem. Should have
modified t-rtems.cfg ( no time )

I've tested pc386 with both video and serial consoles and GDB remote.
All work fine, except that GDB acts weird. ( re: other posting)

I hope this will work for you. It took quite some time to locate the
autoconf error. The remainder was just grunt work.
Unfortunately, I think I've unwound the removal of the IBMPCInitVideo
stuff. Sorry. I REALLY can't spend more time... I've been at this
conversion to 4.0 locally and updating the release since Sept. 8th, and
have yet to compile my network driver.... This is as much as I can do
right now.

I look forward to the next patch to really test i368ex. I did make sure
that the sample tests worked for pc386.

  • Property mode set to 100644
File size: 10.1 KB
Line 
1/*
2 * This software is Copyright (C) 1998 by T.sqware - all rights limited
3 * It is provided in to the public domain "as is", can be freely modified
4 * as far as this copyight notice is kept unchanged, but does not imply
5 * an endorsement by T.sqware of the product in which it is included.
6 *
7 *  $Id$
8 */
9
10#include <rtems.h>
11#include <bsp.h>
12#include <assert.h>
13#include <pcibios.h>
14
15/*
16 * This is simpliest possible PCI BIOS, it assumes that addressing
17 * is flat and that stack is big enough
18 */
19
20
21static int pcibInitialized = 0;
22static unsigned int pcibEntry;
23
24/*
25 * Array to pass data between c and asm parts, at the time of
26 * writing I am not yet that familiar with extended asm feature
27 * of gcc. This code is not on performance path, so we can care
28 * relatively little about performance here
29 */
30static volatile unsigned int pcibExchg[5];
31
32static int pcib_convert_err(int err);
33
34/*
35 * Detects presense of PCI BIOS, returns
36 * error code
37 */
38int
39pcib_init(void)
40{
41  unsigned char *ucp;
42  unsigned char sum;
43  int      i;
44
45  pcibInitialized = 0;
46
47  /* First, we have to look for BIOS-32 */
48  for(ucp=(unsigned char *)0xE0000; ucp < (unsigned char *)0xFFFFF; ucp+=0x10)
49    {
50      if(memcmp(ucp, "_32_", 4) != 0)
51        {
52          continue;
53        }
54
55      /* Got signature, check length  */
56      if(*(ucp + 9) != 1)
57        {
58          continue;
59        }
60
61      /* Verify checksum */
62      sum = 0;
63      for(i=0; i<16; i++)
64        {
65          sum += *(ucp+i);
66        }
67
68      if(sum == 0)
69        {
70          /* found */
71          break;
72        }
73    }
74
75  if(ucp >= (unsigned char *)0xFFFFF)
76    {
77      /* BIOS-32 not found */
78      assert(0);
79      return PCIB_ERR_NOTPRESENT;
80    }
81
82  /* BIOS-32 found, let us find PCI BIOS */
83  ucp += 4;
84
85  pcibExchg[0] = *(unsigned int *)ucp;
86
87  asm ("    pusha");                  /* Push all registers */ 
88  asm ("    movl pcibExchg, %edi");   /* Move entry point to esi */
89  asm ("    movl $0x49435024, %eax"); /* Move signature to eax */
90  asm ("    xorl %ebx, %ebx");        /* Zero ebx */
91  asm ("    pushl %cs");
92  asm ("    call *%edi");             /* Call entry */
93  asm ("    movl %eax, pcibExchg");
94  asm ("    movl %ebx, pcibExchg+4");
95  asm ("    movl %ecx, pcibExchg+8");
96  asm ("    movl %edx, pcibExchg+12");
97  asm ("    popa");
98
99  if((pcibExchg[0] & 0xff) != 0)
100    {
101      /* Not found */
102      assert(0);
103      return PCIB_ERR_NOTPRESENT;
104    }
105
106  /* Found PCI entry point */
107  pcibEntry = pcibExchg[1] + pcibExchg[3];
108
109  /* Let us check whether PCI bios is present */
110  pcibExchg[0] = pcibEntry;
111 
112  asm("    pusha");
113  asm("    movl pcibExchg, %edi");
114  asm("    movb $0xb1, %ah");
115  asm("    movb $0x01, %al");
116  asm ("   pushl %cs");
117  asm("    call *%edi");
118  asm("    movl %eax, pcibExchg");
119  asm("    movl %ebx, pcibExchg+4");
120  asm("    movl %ecx, pcibExchg+8");
121  asm("    movl %edx, pcibExchg+12");
122  asm("    popa");
123
124  if((pcibExchg[0] & 0xff00) != 0)
125    {
126      /* Not found */
127      assert(0);
128      return PCIB_ERR_NOTPRESENT;
129    }
130
131  if(pcibExchg[3] != 0x20494350)
132    {
133      /* Signature does not match */
134      assert(0);
135      return PCIB_ERR_NOTPRESENT;
136    }
137
138  /* Success */
139 
140  pcibInitialized = 1;
141  return PCIB_ERR_SUCCESS;
142}
143
144/*
145 * Find specified device and return its signature: combination
146 * of bus number, device number and function number
147 */
148int
149pcib_find_by_devid(int vendorId, int devId, int idx, int *sig)
150{
151  if(!pcibInitialized)
152    {
153      assert(0);
154      return PCIB_ERR_UNINITIALIZED;
155    }
156
157  pcibExchg[0] = pcibEntry;
158  pcibExchg[1] = vendorId;
159  pcibExchg[2] = devId;
160  pcibExchg[3] = idx;
161
162  asm("    pusha");
163  asm("    movl pcibExchg, %edi");
164  asm("    movb $0xb1, %ah");
165  asm("    movb $0x02, %al");
166  asm("    movl pcibExchg+4, %edx");
167  asm("    movl pcibExchg+8, %ecx");
168  asm("    movl pcibExchg+12, %esi");
169  asm("    pushl %cs");
170  asm("    call *%edi");
171  asm("    movl %eax, pcibExchg");
172  asm("    movl %ebx, pcibExchg+4");
173  asm("    popa");
174
175  *sig = pcibExchg[1] & 0xffff;
176
177  return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
178}
179
180/*
181 * Find specified class code return device signature: combination
182 * of bus number, device number and function number
183 */
184int
185pcib_find_by_class(int classCode, int idx, int *sig)
186{
187  if(!pcibInitialized)
188    {
189      assert(0);
190      return PCIB_ERR_UNINITIALIZED;
191    }
192
193  pcibExchg[0] = pcibEntry;
194  pcibExchg[1] = classCode;
195  pcibExchg[2] = idx;
196
197  asm("    pusha");
198  asm("    movl pcibExchg, %edi");
199  asm("    movb $0xb1, %ah");
200  asm("    movb $0x03, %al");
201  asm("    movl pcibExchg+4, %ecx");
202  asm("    movl pcibExchg+8, %esi");
203  asm("    pushl %cs");
204  asm("    call *%edi");
205  asm("    movl %eax, pcibExchg");
206  asm("    movl %ebx, pcibExchg+4");
207  asm("    popa");
208
209  if((pcibExchg[0] & 0xff00) != 0)
210    {
211      return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
212    }
213
214  *sig = pcibExchg[1] & 0xffff;
215
216  return PCIB_ERR_SUCCESS;
217}
218 
219 
220
221/*
222 * Generate Special Cycle
223 */
224int
225pcib_special_cycle(int busNo, int data)
226{
227  if(!pcibInitialized)
228    {
229      assert(0);
230      return PCIB_ERR_UNINITIALIZED;
231    }
232
233  pcibExchg[0] = pcibEntry;
234  pcibExchg[1] = busNo << 8;
235  pcibExchg[2] = data;
236
237  asm("    pusha");
238  asm("    movl pcibExchg, %edi");
239  asm("    movb $0xb1, %ah");
240  asm("    movb $0x06, %al");
241  asm("    movl pcibExchg+4, %ebx");
242  asm("    movl pcibExchg+8, %edx");
243  asm("    pushl %cs");
244  asm("    call *%edi");
245  asm("    movl %eax, pcibExchg");
246  asm("    movl %ebx, pcibExchg+4");
247  asm("    popa");
248
249  return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
250}
251 
252
253/*
254 * Read byte from config space
255 */
256int
257pcib_conf_read8(int sig, int off, unsigned char *data)
258{
259  if(!pcibInitialized)
260    {
261      assert(0);
262      return PCIB_ERR_UNINITIALIZED;
263    }
264
265  pcibExchg[0] = pcibEntry;
266  pcibExchg[1] = sig;
267  pcibExchg[2] = off;
268
269  asm("    pusha");
270  asm("    movl pcibExchg, %esi");
271  asm("    movb $0xb1, %ah");
272  asm("    movb $0x08, %al");
273  asm("    movl pcibExchg+4, %ebx");
274  asm("    movl pcibExchg+8, %edi");
275  asm("    pushl %cs");
276  asm("    call *%esi");
277  asm("    movl %eax, pcibExchg");
278  asm("    movl %ecx, pcibExchg+4");
279  asm("    popa");
280
281  if((pcibExchg[0] & 0xff00) != 0)
282    {
283      return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
284    }
285
286  *data = (unsigned char)pcibExchg[1] & 0xff;
287
288  return PCIB_ERR_SUCCESS;
289}
290 
291
292/*
293 * Read word from config space
294 */
295int
296pcib_conf_read16(int sig, int off, unsigned short *data)
297{
298  if(!pcibInitialized)
299    {
300      assert(0);
301      return PCIB_ERR_UNINITIALIZED;
302    }
303
304  pcibExchg[0] = pcibEntry;
305  pcibExchg[1] = sig;
306  pcibExchg[2] = off;
307
308  asm("    pusha");
309  asm("    movl pcibExchg, %esi");
310  asm("    movb $0xb1, %ah");
311  asm("    movb $0x09, %al");
312  asm("    movl pcibExchg+4, %ebx");
313  asm("    movl pcibExchg+8, %edi");
314  asm("    pushl %cs");
315  asm("    call *%esi");
316  asm("    movl %eax, pcibExchg");
317  asm("    movl %ecx, pcibExchg+4");
318  asm("    popa");
319
320  if((pcibExchg[0] & 0xff00) != 0)
321    {
322      return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
323    }
324
325  *data = (unsigned short)pcibExchg[1] & 0xffff;
326
327  return PCIB_ERR_SUCCESS;
328}
329 
330
331/*
332 * Read dword from config space
333 */
334int
335pcib_conf_read32(int sig, int off, unsigned int *data)
336{
337  if(!pcibInitialized)
338    {
339      assert(0);
340      return PCIB_ERR_UNINITIALIZED;
341    }
342
343  pcibExchg[0] = pcibEntry;
344  pcibExchg[1] = sig;
345  pcibExchg[2] = off;
346
347  asm("    pusha");
348  asm("    movl pcibExchg, %esi");
349  asm("    movb $0xb1, %ah");
350  asm("    movb $0x0a, %al");
351  asm("    movl pcibExchg+4, %ebx");
352  asm("    movl pcibExchg+8, %edi");
353  asm("    pushl %cs");
354  asm("    call *%esi");
355  asm("    movl %eax, pcibExchg");
356  asm("    movl %ecx, pcibExchg+4");
357  asm("    popa");
358
359  if((pcibExchg[0] & 0xff00) != 0)
360    {
361      return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
362    }
363
364  *data = (unsigned int)pcibExchg[1];
365
366  return PCIB_ERR_SUCCESS;
367}
368 
369
370/*
371 * Write byte into  config space
372 */
373int
374pcib_conf_write8(int sig, int off, unsigned int data)
375{
376  if(!pcibInitialized)
377    {
378      assert(0);
379      return PCIB_ERR_UNINITIALIZED;
380    }
381
382  pcibExchg[0] = pcibEntry;
383  pcibExchg[1] = sig;
384  pcibExchg[2] = off;
385  pcibExchg[3] = data & 0xff;
386
387  asm("    pusha");
388  asm("    movl pcibExchg, %esi");
389  asm("    movb $0xb1, %ah");
390  asm("    movb $0x0b, %al");
391  asm("    movl pcibExchg+4, %ebx");
392  asm("    movl pcibExchg+8, %edi");
393  asm("    movl pcibExchg+12, %ecx");
394  asm("    pushl %cs");
395  asm("    call *%esi");
396  asm("    movl %eax, pcibExchg");
397  asm("    popa");
398
399  return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
400}
401
402/*
403 * Write word into config space
404 */
405int
406pcib_conf_write16(int sig, int off, unsigned int data)
407{
408  if(!pcibInitialized)
409    {
410      assert(0);
411      return PCIB_ERR_UNINITIALIZED;
412    }
413
414  pcibExchg[0] = pcibEntry;
415  pcibExchg[1] = sig;
416  pcibExchg[2] = off;
417  pcibExchg[3] = data & 0xffff;
418
419  asm("    pusha");
420  asm("    movl pcibExchg, %esi");
421  asm("    movb $0xb1, %ah");
422  asm("    movb $0x0c, %al");
423  asm("    movl pcibExchg+4, %ebx");
424  asm("    movl pcibExchg+8, %edi");
425  asm("    movl pcibExchg+12, %ecx");
426  asm("    pushl %cs");
427  asm("    call *%esi");
428  asm("    movl %eax, pcibExchg");
429  asm("    popa");
430
431  return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
432}
433 
434
435
436/*
437 * Write dword into config space
438 */
439int
440pcib_conf_write32(int sig, int off, unsigned int data)
441{
442  if(!pcibInitialized)
443    {
444      assert(0);
445      return PCIB_ERR_UNINITIALIZED;
446    }
447
448  pcibExchg[0] = pcibEntry;
449  pcibExchg[1] = sig;
450  pcibExchg[2] = off;
451  pcibExchg[3] = data;
452
453  asm("    pusha");
454  asm("    movl pcibExchg, %esi");
455  asm("    movb $0xb1, %ah");
456  asm("    movb $0x0d, %al");
457  asm("    movl pcibExchg+4, %ebx");
458  asm("    movl pcibExchg+8, %edi");
459  asm("    movl pcibExchg+12, %ecx");
460  asm("    pushl %cs");
461  asm("    call *%esi");
462  asm("    movl %eax, pcibExchg");
463  asm("    popa");
464
465  return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
466}
467 
468
469static int
470pcib_convert_err(int err)
471{
472  switch(err & 0xff)
473    {
474    case 0:
475      return PCIB_ERR_SUCCESS;
476    case 0x81:
477      return PCIB_ERR_NOFUNC;
478    case 0x83:
479      return PCIB_ERR_BADVENDOR;
480    case 0x86:
481      return PCIB_ERR_DEVNOTFOUND;
482    case 0x87:
483      return PCIB_ERR_BADREG;
484    default:
485      assert(0);
486      break;
487    }
488  return PCIB_ERR_NOFUNC;
489}
490       
491     
492
493
494 
495     
496 
497
498
499
Note: See TracBrowser for help on using the repository browser.