瀏覽代碼

Nearly there...

tags/v0.9.3
Michael Brown 19 年之前
父節點
當前提交
0ccaf5bb83
共有 1 個檔案被更改,包括 383 行新增292 行删除
  1. 383
    292
      src/arch/i386/core/pci_io.c

+ 383
- 292
src/arch/i386/core/pci_io.c 查看文件

@@ -10,279 +10,202 @@
10 10
 ** /usr/src/linux/include/linux/bios32.h
11 11
 ** /usr/src/linux/drivers/net/ne.c
12 12
 */
13
-#ifdef CONFIG_PCI
14 13
 #include "etherboot.h"
14
+#include "init.h"
15 15
 #include "pci.h"
16
+#include "pci_io.h"
17
+#ifdef KEEP_IT_REAL
18
+#include "realmode.h"
19
+#endif
16 20
 
17
-#ifdef	CONFIG_PCI_DIRECT
18
-#define  PCIBIOS_SUCCESSFUL                0x00
21
+#define DEBUG_PCI_IO
19 22
 
20
-#define DEBUG 0
23
+#undef DBG
24
+#ifdef DEBUG_PCI_IO
25
+#define DBG(...) printf ( __VA_ARGS__ )
26
+#else
27
+#define DBG(...)
28
+#endif
21 29
 
22
-/*
23
- * Functions for accessing PCI configuration space with type 1 accesses
30
+/* Macros for direct PCI access */
31
+#define CONFIG_ADDRESS	0xcf8
32
+#define CONFIG_DATA	0xcfc
33
+#define CONFIG_CMD( pci, where ) \
34
+	( 0x80000000 | (pci->busdevfn << 8) | (where & ~3) )
35
+
36
+/* Signatures for PCI BIOS */
37
+#define BIOS_SIG(a,b,c,d)	( ( a<<0 ) + ( b<<8 ) + ( c<<16 ) + ( d<<24 ) )
38
+#define PRINT_BIOS_SIG(x)	( (x) & 0xff ), ( ( (x)>>8 ) & 0xff ), \
39
+				( ( (x)>>16 ) & 0xff ),( ( (x)>>24 ) & 0xff )
40
+#define BIOS32_SIGNATURE	BIOS_SIG ( '_', '3', '2', '_' )
41
+#define PCI_SIGNATURE		BIOS_SIG ( 'P', 'C', 'I', ' ' )
42
+#define PCI_SERVICE		BIOS_SIG ( '$', 'P', 'C', 'I' )
43
+
44
+/* BIOS32 structure as found in PCI BIOS ROM */
45
+struct bios32 {
46
+	unsigned long signature;	/* _32_ */
47
+	unsigned long entry;		/* 32 bit physical address */
48
+	unsigned char revision;		/* Revision level, 0 */
49
+	unsigned char length;		/* Length in paragraphs */
50
+	unsigned char checksum;		/* Should byte sum to zero */
51
+	unsigned char reserved[5];	/* Must be zero */
52
+};
53
+
54
+/* Values returned by BIOS32 service directory */
55
+#define BIOS32_SERVICE_PRESENT		0x00
56
+#define BIOS32_SERVICE_NOT_PRESENT	0x80
57
+#define CF ( 1 << 0 )
58
+
59
+/* PCI BIOS entry point */
60
+#ifndef KEEP_IT_REAL
61
+static unsigned long pcibios32_entry;
62
+#endif
63
+static int have_pcibios;
64
+
65
+/* Macro for calling a 32-bit entry point with flat physical
66
+ * addresses.  Use in a statement such as
67
+ * __asm__ ( FLAT_FAR_CALL_ESI,
68
+ *	     : <output registers>
69
+ *	     : "S" ( entry_point ), <other input registers> );
24 70
  */
71
+#define FLAT_FAR_CALL_ESI "call _virt_to_phys\n\t" \
72
+			  "pushl %%cs\n\t" \
73
+			  "call *%%esi\n\t" \
74
+			  "cli\n\t" \
75
+			  "cld\n\t" \
76
+			  "call _phys_to_virt\n\t"
25 77
 
26
-#define CONFIG_CMD(bus, device_fn, where)   (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3))
78
+/*
79
+ * Functions for accessing PCI configuration space directly with type
80
+ * 1 accesses.
81
+ *
82
+ */
27 83
 
28
-int pcibios_read_config_byte(unsigned int bus, unsigned int device_fn,
29
-			       unsigned int where, uint8_t *value)
30
-{
31
-    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
32
-    *value = inb(0xCFC + (where&3));
33
-    return PCIBIOS_SUCCESSFUL;
84
+static inline int pcidirect_read_config_byte ( struct pci_device *pci,
85
+					       unsigned int where,
86
+					       uint8_t *value ) {
87
+    outl ( CONFIG_CMD ( pci, where ), CONFIG_ADDRESS );
88
+    *value = inb ( CONFIG_DATA + ( where & 3 ) );
89
+    return 0;
34 90
 }
35 91
 
36
-int pcibios_read_config_word (unsigned int bus,
37
-    unsigned int device_fn, unsigned int where, uint16_t *value)
38
-{
39
-    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
40
-    *value = inw(0xCFC + (where&2));
41
-    return PCIBIOS_SUCCESSFUL;
92
+static inline int pcidirect_read_config_word ( struct pci_device *pci,
93
+					       unsigned int where,
94
+					       uint16_t *value ) {
95
+    outl ( CONFIG_CMD ( pci, where ), CONFIG_ADDRESS );
96
+    *value = inw ( CONFIG_DATA + ( where & 2 ) );
97
+    return 0;
42 98
 }
43 99
 
44
-int pcibios_read_config_dword (unsigned int bus, unsigned int device_fn,
45
-				 unsigned int where, uint32_t *value)
46
-{
47
-    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
48
-    *value = inl(0xCFC);
49
-    return PCIBIOS_SUCCESSFUL;
100
+static inline int pcidirect_read_config_dword ( struct pci_device *pci,
101
+						unsigned int where,
102
+						uint32_t *value ) {
103
+    outl ( CONFIG_CMD ( pci, where ), CONFIG_ADDRESS );
104
+    *value = inl ( CONFIG_DATA );
105
+    return 0;
50 106
 }
51 107
 
52
-int pcibios_write_config_byte (unsigned int bus, unsigned int device_fn,
53
-				 unsigned int where, uint8_t value)
54
-{
55
-    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
56
-    outb(value, 0xCFC + (where&3));
57
-    return PCIBIOS_SUCCESSFUL;
108
+static inline int pcidirect_write_config_byte ( struct pci_device *pci,
109
+						unsigned int where,
110
+						uint8_t value ) {
111
+    outl ( CONFIG_CMD ( pci, where ), CONFIG_ADDRESS );
112
+    outb ( value, CONFIG_DATA + ( where & 3 ) );
113
+    return 0;
58 114
 }
59 115
 
60
-int pcibios_write_config_word (unsigned int bus, unsigned int device_fn,
61
-				 unsigned int where, uint16_t value)
62
-{
63
-    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
64
-    outw(value, 0xCFC + (where&2));
65
-    return PCIBIOS_SUCCESSFUL;
116
+static inline int pcidirect_write_config_word ( struct pci_device *pci,
117
+						unsigned int where,
118
+						uint16_t value ) {
119
+    outl ( CONFIG_CMD ( pci, where ), CONFIG_ADDRESS );
120
+    outw ( value, CONFIG_DATA + ( where & 2 ) );
121
+    return 0;
66 122
 }
67 123
 
68
-int pcibios_write_config_dword (unsigned int bus, unsigned int device_fn, unsigned int where, uint32_t value)
69
-{
70
-    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
71
-    outl(value, 0xCFC);
72
-    return PCIBIOS_SUCCESSFUL;
124
+static inline int pcidirect_write_config_dword ( struct pci_device *pci,
125
+						 unsigned int where,
126
+						 uint32_t value ) {
127
+    outl ( CONFIG_CMD ( pci, where ), CONFIG_ADDRESS );
128
+    outl ( value, CONFIG_DATA );
129
+    return 0;
73 130
 }
74 131
 
75
-#undef CONFIG_CMD
76
-
77
-#else	 /* CONFIG_PCI_DIRECT  not defined */
78
-
79
-#if !defined(PCBIOS)
80
-#error "The pcibios can only be used when the PCBIOS support is compiled in"
81
-#endif
82
-
83
-/* Macro for calling the BIOS32 service.  This replaces the old
84
- * bios32_call function.  Use in a statement such as
85
- * __asm__ ( BIOS32_CALL,
86
- *	     : <output registers>
87
- *	     : "S" ( bios32_entry ), <other input registers> );
132
+/*
133
+ * Functions for accessing PCI configuration space directly via the
134
+ * PCI BIOS.
135
+ *
136
+ * Under -DKEEP_IT_REAL, we use INT 1A, otherwise we use the BIOS32
137
+ * interface.
88 138
  */
89
-#define BIOS32_CALL "call _virt_to_phys\n\t" \
90
-		    "pushl %%cs\n\t" \
91
-		    "call *%%esi\n\t" \
92
-		    "cli\n\t" \
93
-		    "cld\n\t" \
94
-		    "call _phys_to_virt\n\t"
95
-
96
-static unsigned long bios32_entry;
97
-static unsigned long pcibios_entry;
98
-
99
-static unsigned long bios32_service(unsigned long service)
100
-{
101
-	unsigned char return_code;	/* %al */
102
-	unsigned long address;		/* %ebx */
103
-	unsigned long length;		/* %ecx */
104
-	unsigned long entry;		/* %edx */
105
-
106
-	__asm__(BIOS32_CALL
107
-		: "=a" (return_code),
108
-		  "=b" (address),
109
-		  "=c" (length),
110
-		  "=d" (entry)
111
-		: "0" (service),
112
-		  "1" (0),
113
-		  "S" (bios32_entry));
114
-
115
-	switch (return_code) {
116
-		case 0:
117
-			return address + entry;
118
-		case 0x80:	/* Not present */
119
-			printf("bios32_service(%d) : not present\n", service);
120
-			return 0;
121
-		default: /* Shouldn't happen */
122
-			printf("bios32_service(%d) : returned %#X????\n",
123
-				service, return_code);
124
-			return 0;
125
-	}
126
-}
127
-
128
-int pcibios_read_config_byte(unsigned int bus,
129
-        unsigned int device_fn, unsigned int where, uint8_t *value)
130
-{
131
-        unsigned long ret;
132
-        unsigned long bx = (bus << 8) | device_fn;
133
-
134
-        __asm__(BIOS32_CALL
135
-                "jc 1f\n\t"
136
-                "xor %%ah, %%ah\n"
137
-                "1:"
138
-                : "=c" (*value),
139
-                  "=a" (ret)
140
-                : "1" (PCIBIOS_READ_CONFIG_BYTE),
141
-                  "b" (bx),
142
-                  "D" ((long) where),
143
-                  "S" (pcibios_entry));
144
-        return (int) (ret & 0xff00) >> 8;
145
-}
146
-
147
-int pcibios_read_config_word(unsigned int bus,
148
-        unsigned int device_fn, unsigned int where, uint16_t *value)
149
-{
150
-        unsigned long ret;
151
-        unsigned long bx = (bus << 8) | device_fn;
152
-
153
-        __asm__(BIOS32_CALL
154
-                "jc 1f\n\t"
155
-                "xor %%ah, %%ah\n"
156
-                "1:"
157
-                : "=c" (*value),
158
-                  "=a" (ret)
159
-                : "1" (PCIBIOS_READ_CONFIG_WORD),
160
-                  "b" (bx),
161
-                  "D" ((long) where),
162
-                  "S" (pcibios_entry));
163
-        return (int) (ret & 0xff00) >> 8;
164
-}
165 139
 
166
-int pcibios_read_config_dword(unsigned int bus,
167
-        unsigned int device_fn, unsigned int where, uint32_t *value)
168
-{
169
-        unsigned long ret;
170
-        unsigned long bx = (bus << 8) | device_fn;
171
-
172
-        __asm__(BIOS32_CALL
173
-                "jc 1f\n\t"
174
-                "xor %%ah, %%ah\n"
175
-                "1:"
176
-                : "=c" (*value),
177
-                  "=a" (ret)
178
-                : "1" (PCIBIOS_READ_CONFIG_DWORD),
179
-                  "b" (bx),
180
-                  "D" ((long) where),
181
-                  "S" (pcibios_entry));
182
-        return (int) (ret & 0xff00) >> 8;
183
-}
184
-
185
-int pcibios_write_config_byte (unsigned int bus,
186
-	unsigned int device_fn, unsigned int where, uint8_t value)
187
-{
188
-	unsigned long ret;
189
-	unsigned long bx = (bus << 8) | device_fn;
190
-
191
-	__asm__(BIOS32_CALL
192
-		"jc 1f\n\t"
193
-		"xor %%ah, %%ah\n"
194
-		"1:"
195
-		: "=a" (ret)
196
-		: "0" (PCIBIOS_WRITE_CONFIG_BYTE),
197
-		  "c" (value),
198
-		  "b" (bx),
199
-		  "D" ((long) where),
200
-		  "S" (pcibios_entry));
201
-	return (int) (ret & 0xff00) >> 8;
202
-}
203
-
204
-int pcibios_write_config_word (unsigned int bus,
205
-	unsigned int device_fn, unsigned int where, uint16_t value)
206
-{
207
-	unsigned long ret;
208
-	unsigned long bx = (bus << 8) | device_fn;
209
-
210
-	__asm__(BIOS32_CALL
211
-		"jc 1f\n\t"
212
-		"xor %%ah, %%ah\n"
213
-		"1:"
214
-		: "=a" (ret)
215
-		: "0" (PCIBIOS_WRITE_CONFIG_WORD),
216
-		  "c" (value),
217
-		  "b" (bx),
218
-		  "D" ((long) where),
219
-		  "S" (pcibios_entry));
220
-	return (int) (ret & 0xff00) >> 8;
221
-}
140
+#ifdef KEEP_IT_REAL
141
+
142
+static void find_pcibios16 ( void ) {
143
+	uint16_t present;
144
+	uint32_t signature;
145
+	uint16_t flags;
146
+	uint16_t revision;
147
+
148
+	/* PCI BIOS installation check */
149
+	REAL_EXEC ( rm_pcibios_check,
150
+		    "int $0x1a\n\t"
151
+		    "pushfw\n\t"
152
+		    "popw %%cx\n\t",
153
+		    4,
154
+		    OUT_CONSTRAINTS ( "=a" ( present ), "=b" ( revision ),
155
+				      "=c" ( flags ), "=d" ( signature ) ),
156
+		    IN_CONSTRAINTS ( "a" ( ( PCIBIOS_PCI_FUNCTION_ID << 8 ) +
157
+					   PCIBIOS_PCI_BIOS_PRESENT ) ),
158
+		    CLOBBER ( "esi", "edi", "ebp" ) );
159
+
160
+	if ( ( flags & CF ) ||
161
+	     ( ( present >> 8 ) != 0 ) ||
162
+	     ( signature != PCI_SIGNATURE ) ) {
163
+		DBG ( "PCI BIOS installation check failed\n" );
164
+		return;
165
+	}
222 166
 
223
-int pcibios_write_config_dword (unsigned int bus,
224
-	unsigned int device_fn, unsigned int where, uint32_t value)
225
-{
226
-	unsigned long ret;
227
-	unsigned long bx = (bus << 8) | device_fn;
228
-
229
-	__asm__(BIOS32_CALL
230
-		"jc 1f\n\t"
231
-		"xor %%ah, %%ah\n"
232
-		"1:"
233
-		: "=a" (ret)
234
-		: "0" (PCIBIOS_WRITE_CONFIG_DWORD),
235
-		  "c" (value),
236
-		  "b" (bx),
237
-		  "D" ((long) where),
238
-		  "S" (pcibios_entry));
239
-	return (int) (ret & 0xff00) >> 8;
167
+	/* We have a PCI BIOS */
168
+	have_pcibios = 1;
169
+	return;
240 170
 }
241 171
 
242
-static void check_pcibios(void)
243
-{
244
-	unsigned long signature;
245
-	unsigned char present_status;
246
-	unsigned char major_revision;
247
-	unsigned char minor_revision;
248
-	int pack;
249
-
250
-	if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
251
-		__asm__(BIOS32_CALL
252
-			"jc 1f\n\t"
253
-			"xor %%ah, %%ah\n"
254
-			"1:\tshl $8, %%eax\n\t"
255
-			"movw %%bx, %%ax"
256
-			: "=d" (signature),
257
-			  "=a" (pack)
258
-			: "1" (PCIBIOS_PCI_BIOS_PRESENT),
259
-			  "S" (pcibios_entry)
260
-			: "bx", "cx");
261
-
262
-		present_status = (pack >> 16) & 0xff;
263
-		major_revision = (pack >> 8) & 0xff;
264
-		minor_revision = pack & 0xff;
265
-		if (present_status || (signature != PCI_SIGNATURE)) {
266
-			printf("ERROR: BIOS32 says PCI BIOS, but no PCI "
267
-				"BIOS????\n");
268
-			pcibios_entry = 0;
269
-		}
270
-#if	DEBUG
271
-		if (pcibios_entry) {
272
-			printf ("pcibios_init : PCI BIOS revision %hhX.%hhX"
273
-				" entry at %#X\n", major_revision,
274
-				minor_revision, pcibios_entry);
275
-		}
276
-#endif
277
-	}
278
-}
172
+INIT_FN ( INIT_PCIBIOS, find_pcibios16, NULL, NULL );
173
+
174
+#define pcibios16_read_write( command, pci, where, value )		\
175
+	( {								\
176
+		uint32_t discard_b, discard_D;				\
177
+		uint16_t ret;						\
178
+									\
179
+		REAL_EXEC ( __FUNCTION__ ,			\
180
+			    "int $0x1a\n\t"				\
181
+			    "jc 1f\n\t"					\
182
+			    "xorl %%eax, %%eax\n\t"			\
183
+			    "\n1:\n\t",					\
184
+			    5,						\
185
+			    OUT_CONSTRAINTS ( "=a" ( ret ),		\
186
+					      "=b" ( discard_b ),	\
187
+					      "=c" ( value ),		\
188
+					      "=D" ( discard_D ) ),	\
189
+			    IN_CONSTRAINTS ( "a" ( command +		\
190
+				    ( PCIBIOS_PCI_FUNCTION_ID << 8 ) ),	\
191
+					     "b" ( pci->busdevfn ),	\
192
+					     "c" ( value ),		\
193
+			    		     "D" ( where ) ),		\
194
+			    CLOBBER ( "edx", "ebp" ) );			\
195
+									\
196
+		( ret >> 8 );						\
197
+	} )
198
+#define pcibios_read_write pcibios16_read_write
199
+
200
+#else /* KEEP_IT_REAL */
279 201
 
280
-static void pcibios_init(void)
281
-{
282
-	union bios32 *check;
283
-	unsigned char sum;
284
-	int i, length;
285
-	bios32_entry = 0;
202
+/*
203
+ * Locate the BIOS32 service directory by scanning for a valid BIOS32
204
+ * structure
205
+ *
206
+ */
207
+static struct bios32 * find_bios32 ( void ) {
208
+	uint32_t address;
286 209
 
287 210
 	/*
288 211
 	 * Follow the standard procedure for locating the BIOS32 Service
@@ -290,63 +213,231 @@ static void pcibios_init(void)
290 213
 	 * 0xe0000 through 0xfffff for a valid BIOS32 structure.
291 214
 	 *
292 215
 	 */
216
+	for ( address = 0xe0000 ; address < 0xffff0 ; address += 16 ) {
217
+		struct bios32 * candidate = phys_to_virt ( address );
218
+		unsigned int length, i;
219
+		unsigned char sum;
293 220
 
294
-	for (check = phys_to_virt(0xe0000); (void *)check <= phys_to_virt(0xffff0); ++check) {
295
-		if (check->fields.signature != BIOS32_SIGNATURE)
221
+		if ( candidate->signature != BIOS32_SIGNATURE )
296 222
 			continue;
297
-		length = check->fields.length * 16;
298
-		if (!length)
223
+
224
+		length = candidate->length * 16;
225
+		if ( ! length )
299 226
 			continue;
300
-		sum = 0;
301
-		for (i = 0; i < length ; ++i)
302
-			sum += check->chars[i];
303
-		if (sum != 0)
227
+
228
+		for ( sum = 0, i = 0 ; i < length ; i++ )
229
+			sum += ( ( char * ) candidate ) [i];
230
+		if ( sum != 0 )
304 231
 			continue;
305
-		if (check->fields.revision != 0) {
306
-			printf("pcibios_init : unsupported revision %d at %#X, mail drew@colorado.edu\n",
307
-				check->fields.revision, check);
232
+
233
+		if ( candidate->revision != 0 ) {
234
+			DBG ( "unsupported BIOS32 revision %d at %#x\n",
235
+			      candidate->revision, address );
308 236
 			continue;
309 237
 		}
310
-#if	DEBUG
311
-		printf("pcibios_init : BIOS32 Service Directory "
312
-			"structure at %#X\n", check);
313
-#endif
314
-		if (!bios32_entry) {
315
-			if (check->fields.entry >= 0x100000) {
316
-				printf("pcibios_init: entry in high "
317
-					"memory, giving up\n");
318
-				return;
319
-			} else {
320
-				bios32_entry = check->fields.entry;
321
-#if	DEBUG
322
-				printf("pcibios_init : BIOS32 Service Directory"
323
-					" entry at %#X\n", bios32_entry);
324
-#endif
325
-			}
326
-		}
238
+
239
+		DBG ( "BIOS32 Service Directory structure at %#x\n", address );
240
+
241
+		return candidate;
327 242
 	}
328
-	if (bios32_entry)
329
-		check_pcibios();
243
+
244
+	return NULL;
330 245
 }
331
-#endif	/* CONFIG_PCI_DIRECT not defined*/
332 246
 
333
-unsigned long pcibios_bus_base(unsigned int bus __unused)
334
-{
335
-	/* architecturally this must be 0 */
336
-	return 0;
247
+/*
248
+ * Look up a service in the BIOS32 service directory
249
+ *
250
+ */
251
+static unsigned long find_bios32_service ( struct bios32 * bios32,
252
+					   unsigned long service ) {
253
+	uint8_t return_code;
254
+	uint32_t address;
255
+	uint32_t length;
256
+	uint32_t entry;
257
+	uint32_t discard;
258
+
259
+	__asm__ ( FLAT_FAR_CALL_ESI
260
+		  : "=a" ( return_code ), "=b" ( address ),
261
+		    "=c" ( length ), "=d" ( entry ), "=S" ( discard )
262
+		  : "a" ( service ), "b" ( 0 ), "S" ( bios32->entry )
263
+		  : "edi", "ebp" );
264
+
265
+	switch ( return_code ) {
266
+	case BIOS32_SERVICE_PRESENT:
267
+		return ( address + entry );
268
+	case BIOS32_SERVICE_NOT_PRESENT:
269
+		DBG ( "BIOS32 service %c%c%c%c : not present\n",
270
+		      PRINT_BIOS_SIG ( service ) );
271
+		return 0;
272
+	default: /* Shouldn't happen */
273
+		DBG ( "BIOS32 returned %#x for service %c%c%c%c!\n",
274
+		      return_code, PRINT_BIOS_SIG ( service ) );
275
+		return 0;
276
+	}
337 277
 }
338 278
 
339
-void find_pci(int type, struct pci_device *dev)
340
-{
341
-#ifndef	CONFIG_PCI_DIRECT
342
-	if (!pcibios_entry) {
343
-		pcibios_init();
279
+static void find_pcibios32 ( void ) {
280
+	struct bios32 *bios32;
281
+	uint32_t signature;
282
+	uint16_t present;
283
+	uint32_t flags;
284
+	uint16_t revision;
285
+	uint32_t discard;
286
+
287
+	/* Locate BIOS32 service directory */
288
+	bios32 = find_bios32 ();
289
+	if ( ! bios32 ) {
290
+		DBG ( "No BIOS32\n" );
291
+		return;
292
+	}
293
+
294
+	/* Locate PCI BIOS service */
295
+	pcibios32_entry = find_bios32_service ( bios32, PCI_SERVICE );
296
+	if ( ! pcibios32_entry ) {
297
+		DBG ( "No PCI BIOS\n" );
298
+		return;
344 299
 	}
345
-	if (!pcibios_entry) {
346
-		printf("pci_init: no BIOS32 detected\n");
300
+	
301
+	/* PCI BIOS installation check */
302
+	__asm__ ( FLAT_FAR_CALL_ESI
303
+		  "pushfl\n\t"
304
+		  "popl %%ecx\n\t"
305
+		  : "=a" ( present ), "=b" ( revision ), "=c" ( flags ),
306
+		    "=d" ( signature ), "=S" ( discard )
307
+		  : "a" ( ( PCIBIOS_PCI_FUNCTION_ID << 8 )
308
+			  + PCIBIOS_PCI_BIOS_PRESENT ),
309
+		    "S" ( pcibios32_entry )
310
+		  : "edi", "ebp" );
311
+
312
+	if ( ( flags & CF ) ||
313
+	     ( ( present >> 8 ) != 0 ) ||
314
+	     ( signature != PCI_SIGNATURE ) ) {
315
+		DBG ( "PCI BIOS installation check failed\n" );
347 316
 		return;
348 317
 	}
349
-#endif
350
-	return scan_pci_bus(type, dev);
318
+
319
+	/* We have a PCI BIOS */
320
+	have_pcibios = 1;
321
+	return;
322
+}
323
+
324
+INIT_FN ( INIT_PCIBIOS, find_pcibios32, NULL, NULL );
325
+
326
+#define pcibios32_read_write( command, pci, where, value )		\
327
+	( {								\
328
+		uint32_t discard_b, discard_D, discard_S;		\
329
+		uint16_t ret;						\
330
+									\
331
+		__asm__ ( FLAT_FAR_CALL_ESI				\
332
+			  "jc 1f\n\t"					\
333
+			  "xorl %%eax, %%eax\n\t"			\
334
+			  "\n1:\n\t"					\
335
+			  : "=a" ( ret ), "=b" ( discard_b ),		\
336
+			    "=c" ( value ),				\
337
+			    "=S" ( discard_S ), "=D" ( discard_D )	\
338
+			  : "a" ( ( PCIBIOS_PCI_FUNCTION_ID << 8 )	\
339
+				  + command ),			       	\
340
+			    "b" ( pci->busdevfn ), "c" ( value ),	\
341
+			    "D" ( where ), "S" ( pcibios32_entry )	\
342
+			  : "edx", "ebp" );				\
343
+									\
344
+		( ret >> 8 );						\
345
+	} )
346
+#define pcibios_read_write pcibios32_read_write
347
+
348
+#endif /* KEEP_IT_REAL */
349
+
350
+static inline int pcibios_read_config_byte ( struct pci_device *pci,
351
+					     unsigned int where,
352
+					     uint8_t *value ) {
353
+	return pcibios_read_write ( PCIBIOS_READ_CONFIG_BYTE,
354
+				    pci, where, *value );
355
+}
356
+
357
+static inline int pcibios_read_config_word ( struct pci_device *pci,
358
+					     unsigned int where,
359
+					     uint16_t *value ) {
360
+	return pcibios_read_write ( PCIBIOS_READ_CONFIG_WORD,
361
+				    pci, where, *value );
362
+}
363
+
364
+static inline int pcibios_read_config_dword ( struct pci_device *pci,
365
+					      unsigned int where,
366
+					      uint32_t *value ) {
367
+	return pcibios_read_write ( PCIBIOS_READ_CONFIG_DWORD,
368
+				    pci, where, *value );
369
+}
370
+
371
+static inline int pcibios_write_config_byte ( struct pci_device *pci,
372
+					      unsigned int where,
373
+					      uint8_t value ) {
374
+	return pcibios_read_write ( PCIBIOS_WRITE_CONFIG_BYTE,
375
+				    pci, where, value );
376
+}
377
+
378
+static inline int pcibios_write_config_word ( struct pci_device *pci,
379
+					      unsigned int where,
380
+					      uint16_t value ) {
381
+	return pcibios_read_write ( PCIBIOS_WRITE_CONFIG_WORD,
382
+				    pci, where, value );
383
+}
384
+
385
+static inline int pcibios_write_config_dword ( struct pci_device *pci,
386
+					       unsigned int where,
387
+					       uint32_t value ) {
388
+	return pcibios_read_write ( PCIBIOS_WRITE_CONFIG_DWORD,
389
+				    pci, where, value );
390
+}
391
+
392
+/*
393
+ * Functions for accessing PCI configuration space via the PCI BIOS if
394
+ * present, otherwise directly via type 1 accesses.
395
+ *
396
+ */
397
+
398
+int pci_read_config_byte ( struct pci_device *pci, unsigned int where,
399
+			   uint8_t *value ) {
400
+	return have_pcibios ?
401
+		pcibios_read_config_byte ( pci, where, value ) :
402
+		pcidirect_read_config_byte ( pci, where, value );
403
+}
404
+		
405
+int pci_read_config_word ( struct pci_device *pci, unsigned int where,
406
+			   uint16_t *value ) {
407
+	return have_pcibios ?
408
+		pcibios_read_config_word ( pci, where, value ) :
409
+		pcidirect_read_config_word ( pci, where, value );
410
+}
411
+		
412
+int pci_read_config_dword ( struct pci_device *pci, unsigned int where,
413
+			    uint32_t *value ) {
414
+	return have_pcibios ?
415
+		pcibios_read_config_dword ( pci, where, value ) :
416
+		pcidirect_read_config_dword ( pci, where, value );
417
+}
418
+		
419
+int pci_write_config_byte ( struct pci_device *pci, unsigned int where,
420
+			    uint8_t value ) {
421
+	return have_pcibios ?
422
+		pcibios_write_config_byte ( pci, where, value ) :
423
+		pcidirect_write_config_byte ( pci, where, value );
424
+}
425
+		
426
+int pci_write_config_word ( struct pci_device *pci, unsigned int where,
427
+			    uint16_t value ) {
428
+	return have_pcibios ?
429
+		pcibios_write_config_word ( pci, where, value ) :
430
+		pcidirect_write_config_word ( pci, where, value );
431
+}
432
+		
433
+int pci_write_config_dword ( struct pci_device *pci, unsigned int where,
434
+			     uint32_t value ) {
435
+	return have_pcibios ?
436
+		pcibios_write_config_dword ( pci, where, value ) :
437
+		pcidirect_write_config_dword ( pci, where, value );
438
+}
439
+		
440
+unsigned long pci_bus_base ( struct pci_device *pci __unused ) {
441
+	/* architecturally this must be 0 */
442
+	return 0;
351 443
 }
352
-#endif /* CONFIG_PCI */

Loading…
取消
儲存