Przeglądaj źródła

Read number of PCI buses returned by BIOS so that we can scan more

quickly.
tags/v0.9.3
Michael Brown 19 lat temu
rodzic
commit
6e5a3858bf
3 zmienionych plików z 37 dodań i 12 usunięć
  1. 19
    12
      src/arch/i386/core/pci_io.c
  2. 11
    0
      src/drivers/bus/pci.c
  3. 7
    0
      src/include/pci.h

+ 19
- 12
src/arch/i386/core/pci_io.c Wyświetl plik

56
 /* Macro for calling a 32-bit entry point with flat physical
56
 /* Macro for calling a 32-bit entry point with flat physical
57
  * addresses.  Use in a statement such as
57
  * addresses.  Use in a statement such as
58
  * __asm__ ( FLAT_FAR_CALL_ESI,
58
  * __asm__ ( FLAT_FAR_CALL_ESI,
59
- *	     : <output registers>
59
+ *	     : "=S" ( discard, or real output ), <other output registers>
60
  *	     : "S" ( entry_point ), <other input registers> );
60
  *	     : "S" ( entry_point ), <other input registers> );
61
+ * "=S" *must* be specified as an output, otherwise the compiler will
62
+ * assume that it remains unaltered.
61
  */
63
  */
62
 #define FLAT_FAR_CALL_ESI "call _virt_to_phys\n\t" \
64
 #define FLAT_FAR_CALL_ESI "call _virt_to_phys\n\t" \
63
 			  "pushl %%cs\n\t" \
65
 			  "pushl %%cs\n\t" \
135
 	uint32_t signature;
137
 	uint32_t signature;
136
 	uint16_t flags;
138
 	uint16_t flags;
137
 	uint16_t revision;
139
 	uint16_t revision;
140
+	uint8_t max_bus;
138
 
141
 
139
 	/* PCI BIOS installation check */
142
 	/* PCI BIOS installation check */
140
 	REAL_EXEC ( rm_pcibios_check,
143
 	REAL_EXEC ( rm_pcibios_check,
141
 		    "int $0x1a\n\t"
144
 		    "int $0x1a\n\t"
142
 		    "pushfw\n\t"
145
 		    "pushfw\n\t"
143
-		    "popw %%cx\n\t",
144
-		    4,
146
+		    "popw %%si\n\t",
147
+		    5,
145
 		    OUT_CONSTRAINTS ( "=a" ( present ), "=b" ( revision ),
148
 		    OUT_CONSTRAINTS ( "=a" ( present ), "=b" ( revision ),
146
-				      "=c" ( flags ), "=d" ( signature ) ),
149
+				      "=c" ( max_bus ), "=d" ( signature ),
150
+				      "=S" ( flags ) ),
147
 		    IN_CONSTRAINTS ( "a" ( ( PCIBIOS_PCI_FUNCTION_ID << 8 ) +
151
 		    IN_CONSTRAINTS ( "a" ( ( PCIBIOS_PCI_FUNCTION_ID << 8 ) +
148
 					   PCIBIOS_PCI_BIOS_PRESENT ) ),
152
 					   PCIBIOS_PCI_BIOS_PRESENT ) ),
149
-		    CLOBBER ( "esi", "edi", "ebp" ) );
153
+		    CLOBBER ( "edi", "ebp" ) );
150
 
154
 
151
 	if ( ( flags & CF ) ||
155
 	if ( ( flags & CF ) ||
152
 	     ( ( present >> 8 ) != 0 ) ||
156
 	     ( ( present >> 8 ) != 0 ) ||
156
 	}
160
 	}
157
 
161
 
158
 	/* We have a PCI BIOS */
162
 	/* We have a PCI BIOS */
159
-	DBG ( "Found 16-bit PCI BIOS interface\n" );
163
+	DBG ( "Found 16-bit PCI BIOS interface with %d buses\n", max_bus + 1 );
160
 	have_pcibios = 1;
164
 	have_pcibios = 1;
165
+	pci_max_bus = max_bus;
161
 	return;
166
 	return;
162
 }
167
 }
163
 
168
 
280
 	uint16_t present;
285
 	uint16_t present;
281
 	uint32_t flags;
286
 	uint32_t flags;
282
 	uint16_t revision;
287
 	uint16_t revision;
283
-	uint32_t discard;
288
+	uint8_t max_bus;
284
 
289
 
285
 	/* Locate BIOS32 service directory */
290
 	/* Locate BIOS32 service directory */
286
 	bios32 = find_bios32 ();
291
 	bios32 = find_bios32 ();
299
 	/* PCI BIOS installation check */
304
 	/* PCI BIOS installation check */
300
 	__asm__ ( FLAT_FAR_CALL_ESI
305
 	__asm__ ( FLAT_FAR_CALL_ESI
301
 		  "pushfl\n\t"
306
 		  "pushfl\n\t"
302
-		  "popl %%ecx\n\t"
303
-		  : "=a" ( present ), "=b" ( revision ), "=c" ( flags ),
304
-		    "=d" ( signature ), "=S" ( discard )
307
+		  "popl %%esi\n\t"
308
+		  : "=a" ( present ), "=b" ( revision ), "=c" ( max_bus ),
309
+		    "=d" ( signature ), "=S" ( flags )
305
 		  : "a" ( ( PCIBIOS_PCI_FUNCTION_ID << 8 )
310
 		  : "a" ( ( PCIBIOS_PCI_FUNCTION_ID << 8 )
306
 			  + PCIBIOS_PCI_BIOS_PRESENT ),
311
 			  + PCIBIOS_PCI_BIOS_PRESENT ),
307
 		    "S" ( pcibios32_entry )
312
 		    "S" ( pcibios32_entry )
315
 	}
320
 	}
316
 
321
 
317
 	/* We have a PCI BIOS */
322
 	/* We have a PCI BIOS */
318
-	DBG ( "Found 32-bit PCI BIOS interface at %#x\n", pcibios32_entry );
323
+	DBG ( "Found 32-bit PCI BIOS interface at %#x with %d bus(es)\n",
324
+	      pcibios32_entry, max_bus + 1 );
319
 	have_pcibios = 1;
325
 	have_pcibios = 1;
326
+	pci_max_bus = max_bus;
320
 	return;
327
 	return;
321
 }
328
 }
322
 
329
 
435
 		pcibios_write_config_dword ( pci, where, value ) :
442
 		pcibios_write_config_dword ( pci, where, value ) :
436
 		pcidirect_write_config_dword ( pci, where, value );
443
 		pcidirect_write_config_dword ( pci, where, value );
437
 }
444
 }
438
-		
445
+
439
 unsigned long pci_bus_base ( struct pci_device *pci __unused ) {
446
 unsigned long pci_bus_base ( struct pci_device *pci __unused ) {
440
 	/* architecturally this must be 0 */
447
 	/* architecturally this must be 0 */
441
 	return 0;
448
 	return 0;

+ 11
- 0
src/drivers/bus/pci.c Wyświetl plik

9
 DEV_BUS( struct pci_device, pci_dev );
9
 DEV_BUS( struct pci_device, pci_dev );
10
 static char pci_magic[0]; /* guaranteed unique symbol */
10
 static char pci_magic[0]; /* guaranteed unique symbol */
11
 
11
 
12
+/*
13
+ * pci_io.c may know how many buses we have, in which case it can
14
+ * overwrite this value.
15
+ *
16
+ */
17
+unsigned int pci_max_bus = 0xff;
18
+
12
 /*
19
 /*
13
  * Fill in parameters (vendor & device ids, class, membase etc.) for a
20
  * Fill in parameters (vendor & device ids, class, membase etc.) for a
14
  * PCI device based on bus & devfn.
21
  * PCI device based on bus & devfn.
18
 static int fill_pci_device ( struct pci_device *pci ) {
25
 static int fill_pci_device ( struct pci_device *pci ) {
19
 	uint32_t l;
26
 	uint32_t l;
20
 	int reg;
27
 	int reg;
28
+
29
+	/* Check bus is within range */
30
+	if ( PCI_BUS ( pci->busdevfn ) > pci_max_bus )
31
+		return 0;
21
 	
32
 	
22
 	/* Check to see if there's anything physically present.
33
 	/* Check to see if there's anything physically present.
23
 	 */
34
 	 */

+ 7
- 0
src/include/pci.h Wyświetl plik

318
 				    uint32_t value );
318
 				    uint32_t value );
319
 extern unsigned long pci_bus_base ( struct pci_device *dev );
319
 extern unsigned long pci_bus_base ( struct pci_device *dev );
320
 
320
 
321
+/*
322
+ * pci_io.c is allowed to overwrite pci_max_bus if it knows what the
323
+ * highest bus in the system will be.
324
+ *
325
+ */
326
+extern unsigned int pci_max_bus;
327
+
321
 /*
328
 /*
322
  * Functions in pci.c
329
  * Functions in pci.c
323
  *
330
  *

Ładowanie…
Anuluj
Zapisz