Parcourir la source

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

quickly.
tags/v0.9.3
Michael Brown il y a 19 ans
Parent
révision
6e5a3858bf
3 fichiers modifiés avec 37 ajouts et 12 suppressions
  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 Voir le fichier

@@ -56,8 +56,10 @@ static int have_pcibios;
56 56
 /* Macro for calling a 32-bit entry point with flat physical
57 57
  * addresses.  Use in a statement such as
58 58
  * __asm__ ( FLAT_FAR_CALL_ESI,
59
- *	     : <output registers>
59
+ *	     : "=S" ( discard, or real output ), <other output registers>
60 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 64
 #define FLAT_FAR_CALL_ESI "call _virt_to_phys\n\t" \
63 65
 			  "pushl %%cs\n\t" \
@@ -135,18 +137,20 @@ static void find_pcibios16 ( void ) {
135 137
 	uint32_t signature;
136 138
 	uint16_t flags;
137 139
 	uint16_t revision;
140
+	uint8_t max_bus;
138 141
 
139 142
 	/* PCI BIOS installation check */
140 143
 	REAL_EXEC ( rm_pcibios_check,
141 144
 		    "int $0x1a\n\t"
142 145
 		    "pushfw\n\t"
143
-		    "popw %%cx\n\t",
144
-		    4,
146
+		    "popw %%si\n\t",
147
+		    5,
145 148
 		    OUT_CONSTRAINTS ( "=a" ( present ), "=b" ( revision ),
146
-				      "=c" ( flags ), "=d" ( signature ) ),
149
+				      "=c" ( max_bus ), "=d" ( signature ),
150
+				      "=S" ( flags ) ),
147 151
 		    IN_CONSTRAINTS ( "a" ( ( PCIBIOS_PCI_FUNCTION_ID << 8 ) +
148 152
 					   PCIBIOS_PCI_BIOS_PRESENT ) ),
149
-		    CLOBBER ( "esi", "edi", "ebp" ) );
153
+		    CLOBBER ( "edi", "ebp" ) );
150 154
 
151 155
 	if ( ( flags & CF ) ||
152 156
 	     ( ( present >> 8 ) != 0 ) ||
@@ -156,8 +160,9 @@ static void find_pcibios16 ( void ) {
156 160
 	}
157 161
 
158 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 164
 	have_pcibios = 1;
165
+	pci_max_bus = max_bus;
161 166
 	return;
162 167
 }
163 168
 
@@ -280,7 +285,7 @@ static void find_pcibios32 ( void ) {
280 285
 	uint16_t present;
281 286
 	uint32_t flags;
282 287
 	uint16_t revision;
283
-	uint32_t discard;
288
+	uint8_t max_bus;
284 289
 
285 290
 	/* Locate BIOS32 service directory */
286 291
 	bios32 = find_bios32 ();
@@ -299,9 +304,9 @@ static void find_pcibios32 ( void ) {
299 304
 	/* PCI BIOS installation check */
300 305
 	__asm__ ( FLAT_FAR_CALL_ESI
301 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 310
 		  : "a" ( ( PCIBIOS_PCI_FUNCTION_ID << 8 )
306 311
 			  + PCIBIOS_PCI_BIOS_PRESENT ),
307 312
 		    "S" ( pcibios32_entry )
@@ -315,8 +320,10 @@ static void find_pcibios32 ( void ) {
315 320
 	}
316 321
 
317 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 325
 	have_pcibios = 1;
326
+	pci_max_bus = max_bus;
320 327
 	return;
321 328
 }
322 329
 
@@ -435,7 +442,7 @@ int pci_write_config_dword ( struct pci_device *pci, unsigned int where,
435 442
 		pcibios_write_config_dword ( pci, where, value ) :
436 443
 		pcidirect_write_config_dword ( pci, where, value );
437 444
 }
438
-		
445
+
439 446
 unsigned long pci_bus_base ( struct pci_device *pci __unused ) {
440 447
 	/* architecturally this must be 0 */
441 448
 	return 0;

+ 11
- 0
src/drivers/bus/pci.c Voir le fichier

@@ -9,6 +9,13 @@
9 9
 DEV_BUS( struct pci_device, pci_dev );
10 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 20
  * Fill in parameters (vendor & device ids, class, membase etc.) for a
14 21
  * PCI device based on bus & devfn.
@@ -18,6 +25,10 @@ static char pci_magic[0]; /* guaranteed unique symbol */
18 25
 static int fill_pci_device ( struct pci_device *pci ) {
19 26
 	uint32_t l;
20 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 33
 	/* Check to see if there's anything physically present.
23 34
 	 */

+ 7
- 0
src/include/pci.h Voir le fichier

@@ -318,6 +318,13 @@ extern int pci_write_config_dword ( struct pci_device *dev, unsigned int where,
318 318
 				    uint32_t value );
319 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 329
  * Functions in pci.c
323 330
  *

Chargement…
Annuler
Enregistrer