1
2
3
4
/*
* QEMU PCI bus manager
*
* Copyright ( c ) 2004 Fabrice Bellard
ths
authored
18 years ago
5
*
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the "Software" ), to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED "AS IS" , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE .
*/
24
25
26
27
# include "hw.h"
# include "pci.h"
# include "console.h"
# include "net.h"
28
# include "virtio-net.h"
29
30
31
// # define DEBUG_PCI
32
33
34
struct PCIBus {
int bus_num ;
int devfn_min ;
35
pci_set_irq_fn set_irq ;
36
pci_map_irq_fn map_irq ;
37
uint32_t config_reg ; /* XXX: suppress */
38
39
/* low level pic */
SetIRQFunc * low_set_irq ;
40
qemu_irq * irq_opaque ;
41
PCIDevice * devices [ 256 ];
42
43
PCIDevice * parent_dev ;
PCIBus * next ;
44
45
/* The bus IRQ state is the logical OR of the connected devices .
Keep a count of the number of devices with raised IRQs . */
46
int nirq ;
47
int irq_count [];
48
};
49
50
static void pci_update_mappings ( PCIDevice * d );
51
static void pci_set_irq ( void * opaque , int irq_num , int level );
52
53
target_phys_addr_t pci_mem_base ;
54
55
static uint16_t pci_default_sub_vendor_id = PCI_SUBVENDOR_ID_REDHAT_QUMRANET ;
static uint16_t pci_default_sub_device_id = PCI_SUBDEVICE_ID_QEMU ;
56
static int pci_irq_index ;
57
58
static PCIBus * first_bus ;
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
static void pcibus_save ( QEMUFile * f , void * opaque )
{
PCIBus * bus = ( PCIBus * ) opaque ;
int i ;
qemu_put_be32 ( f , bus -> nirq );
for ( i = 0 ; i < bus -> nirq ; i ++ )
qemu_put_be32 ( f , bus -> irq_count [ i ]);
}
static int pcibus_load ( QEMUFile * f , void * opaque , int version_id )
{
PCIBus * bus = ( PCIBus * ) opaque ;
int i , nirq ;
if ( version_id != 1 )
return - EINVAL ;
nirq = qemu_get_be32 ( f );
if ( bus -> nirq != nirq ) {
fprintf ( stderr , "pcibus_load: nirq mismatch: src=%d dst=%d \n " ,
nirq , bus -> nirq );
return - EINVAL ;
}
for ( i = 0 ; i < nirq ; i ++ )
bus -> irq_count [ i ] = qemu_get_be32 ( f );
return 0 ;
}
90
PCIBus * pci_register_bus ( pci_set_irq_fn set_irq , pci_map_irq_fn map_irq ,
91
qemu_irq * pic , int devfn_min , int nirq )
92
93
{
PCIBus * bus ;
94
95
static int nbus = 0 ;
96
bus = qemu_mallocz ( sizeof ( PCIBus ) + ( nirq * sizeof ( int )));
97
bus -> set_irq = set_irq ;
98
bus -> map_irq = map_irq ;
99
100
bus -> irq_opaque = pic ;
bus -> devfn_min = devfn_min ;
101
bus -> nirq = nirq ;
102
first_bus = bus ;
103
register_savevm ( "PCIBUS" , nbus ++ , 1 , pcibus_save , pcibus_load , bus );
104
105
return bus ;
}
106
107
static PCIBus * pci_register_secondary_bus ( PCIDevice * dev , pci_map_irq_fn map_irq )
108
109
110
111
112
113
114
115
116
117
{
PCIBus * bus ;
bus = qemu_mallocz ( sizeof ( PCIBus ));
bus -> map_irq = map_irq ;
bus -> parent_dev = dev ;
bus -> next = dev -> bus -> next ;
dev -> bus -> next = bus ;
return bus ;
}
118
119
120
121
122
int pci_bus_num ( PCIBus * s )
{
return s -> bus_num ;
}
123
void pci_device_save ( PCIDevice * s , QEMUFile * f )
124
{
125
126
127
int i ;
qemu_put_be32 ( f , 2 ); /* PCI device version */
128
qemu_put_buffer ( f , s -> config , 256 );
129
130
for ( i = 0 ; i < 4 ; i ++ )
qemu_put_be32 ( f , s -> irq_state [ i ]);
131
132
}
133
int pci_device_load ( PCIDevice * s , QEMUFile * f )
134
{
135
uint32_t version_id ;
136
137
int i ;
138
version_id = qemu_get_be32 ( f );
139
if ( version_id > 2 )
140
141
return - EINVAL ;
qemu_get_buffer ( f , s -> config , 256 );
142
pci_update_mappings ( s );
143
144
145
146
147
if ( version_id >= 2 )
for ( i = 0 ; i < 4 ; i ++ )
s -> irq_state [ i ] = qemu_get_be32 ( f );
148
149
150
return 0 ;
}
151
152
153
154
155
156
157
158
159
160
static int pci_set_default_subsystem_id ( PCIDevice * pci_dev )
{
uint16_t * id ;
id = ( void * )( & pci_dev -> config [ PCI_SUBVENDOR_ID ]);
id [ 0 ] = cpu_to_le16 ( pci_default_sub_vendor_id );
id [ 1 ] = cpu_to_le16 ( pci_default_sub_device_id );
return 0 ;
}
161
/* -1 for devfn means auto assign */
ths
authored
18 years ago
162
PCIDevice * pci_register_device ( PCIBus * bus , const char * name ,
163
int instance_size , int devfn ,
ths
authored
18 years ago
164
PCIConfigReadFunc * config_read ,
165
166
PCIConfigWriteFunc * config_write )
{
167
PCIDevice * pci_dev ;
168
169
170
if ( pci_irq_index >= PCI_DEVICES_MAX )
return NULL ;
ths
authored
18 years ago
171
172
if ( devfn < 0 ) {
173
174
for ( devfn = bus -> devfn_min ; devfn < 256 ; devfn += 8 ) {
if ( ! bus -> devices [ devfn ])
175
176
177
178
179
180
181
182
goto found ;
}
return NULL ;
found : ;
}
pci_dev = qemu_mallocz ( instance_size );
if ( ! pci_dev )
return NULL ;
183
pci_dev -> bus = bus ;
184
185
pci_dev -> devfn = devfn ;
pstrcpy ( pci_dev -> name , sizeof ( pci_dev -> name ), name );
186
memset ( pci_dev -> irq_state , 0 , sizeof ( pci_dev -> irq_state ));
187
pci_set_default_subsystem_id ( pci_dev );
188
189
190
191
192
if ( ! config_read )
config_read = pci_default_read_config ;
if ( ! config_write )
config_write = pci_default_write_config ;
193
194
pci_dev -> config_read = config_read ;
pci_dev -> config_write = config_write ;
195
pci_dev -> irq_index = pci_irq_index ++ ;
196
bus -> devices [ devfn ] = pci_dev ;
197
pci_dev -> irq = qemu_allocate_irqs ( pci_set_irq , pci_dev , 4 );
198
199
200
return pci_dev ;
}
ths
authored
18 years ago
201
202
void pci_register_io_region ( PCIDevice * pci_dev , int region_num ,
uint32_t size , int type ,
203
204
205
PCIMapIORegionFunc * map_func )
{
PCIIORegion * r ;
206
uint32_t addr ;
207
208
if (( unsigned int ) region_num >= PCI_NUM_REGIONS )
209
210
211
212
213
214
return ;
r = & pci_dev -> io_regions [ region_num ];
r -> addr = - 1 ;
r -> size = size ;
r -> type = type ;
r -> map_func = map_func ;
215
216
217
218
219
220
if ( region_num == PCI_ROM_SLOT ) {
addr = 0x30 ;
} else {
addr = 0x10 + region_num * 4 ;
}
* ( uint32_t * )( pci_dev -> config + addr ) = cpu_to_le32 ( type );
221
222
}
223
static target_phys_addr_t pci_to_cpu_addr ( target_phys_addr_t addr )
224
{
225
return addr + pci_mem_base ;
226
227
}
228
229
230
231
static void pci_update_mappings ( PCIDevice * d )
{
PCIIORegion * r ;
int cmd , i ;
232
uint32_t last_addr , new_addr , config_ofs ;
ths
authored
18 years ago
233
234
cmd = le16_to_cpu ( * ( uint16_t * )( d -> config + PCI_COMMAND ));
235
for ( i = 0 ; i < PCI_NUM_REGIONS ; i ++ ) {
236
r = & d -> io_regions [ i ];
237
238
239
240
241
if ( i == PCI_ROM_SLOT ) {
config_ofs = 0x30 ;
} else {
config_ofs = 0x10 + i * 4 ;
}
242
243
244
if ( r -> size != 0 ) {
if ( r -> type & PCI_ADDRESS_SPACE_IO ) {
if ( cmd & PCI_COMMAND_IO ) {
ths
authored
18 years ago
245
new_addr = le32_to_cpu ( * ( uint32_t * )( d -> config +
246
config_ofs ));
247
248
249
250
251
252
253
254
255
256
257
258
new_addr = new_addr & ~ ( r -> size - 1 );
last_addr = new_addr + r -> size - 1 ;
/* NOTE: we have only 64K ioports on PC */
if ( last_addr <= new_addr || new_addr == 0 ||
last_addr >= 0x10000 ) {
new_addr = - 1 ;
}
} else {
new_addr = - 1 ;
}
} else {
if ( cmd & PCI_COMMAND_MEMORY ) {
ths
authored
18 years ago
259
new_addr = le32_to_cpu ( * ( uint32_t * )( d -> config +
260
261
262
263
config_ofs ));
/* the ROM slot has a specific enable bit */
if ( i == PCI_ROM_SLOT && ! ( new_addr & 1 ))
goto no_mem_map ;
264
265
266
267
268
269
270
271
272
273
274
new_addr = new_addr & ~ ( r -> size - 1 );
last_addr = new_addr + r -> size - 1 ;
/* NOTE: we do not support wrapping */
/* XXX : as we cannot support really dynamic
mappings , we handle specific values as invalid
mappings . */
if ( last_addr <= new_addr || new_addr == 0 ||
last_addr == - 1 ) {
new_addr = - 1 ;
}
} else {
275
no_mem_map :
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
new_addr = - 1 ;
}
}
/* now do the real mapping */
if ( new_addr != r -> addr ) {
if ( r -> addr != - 1 ) {
if ( r -> type & PCI_ADDRESS_SPACE_IO ) {
int class ;
/* NOTE : specific hack for IDE in PC case :
only one byte must be mapped . */
class = d -> config [ 0x0a ] | ( d -> config [ 0x0b ] << 8 );
if ( class == 0x0101 && r -> size == 4 ) {
isa_unassign_ioport ( r -> addr + 2 , 1 );
} else {
isa_unassign_ioport ( r -> addr , r -> size );
}
} else {
293
cpu_register_physical_memory ( pci_to_cpu_addr ( r -> addr ),
ths
authored
18 years ago
294
r -> size ,
295
IO_MEM_UNASSIGNED );
296
qemu_unregister_coalesced_mmio ( r -> addr , r -> size );
297
298
299
300
301
302
303
304
305
306
307
}
}
r -> addr = new_addr ;
if ( r -> addr != - 1 ) {
r -> map_func ( d , i , r -> addr , r -> size , r -> type );
}
}
}
}
}
ths
authored
18 years ago
308
uint32_t pci_default_read_config ( PCIDevice * d ,
309
uint32_t address , int len )
310
{
311
uint32_t val ;
ths
authored
18 years ago
312
313
314
315
switch ( len ) {
default :
case 4 :
ths
authored
18 years ago
316
317
318
319
320
321
322
323
324
325
326
327
328
if ( address <= 0xfc ) {
val = le32_to_cpu ( * ( uint32_t * )( d -> config + address ));
break ;
}
/* fall through */
case 2 :
if ( address <= 0xfe ) {
val = le16_to_cpu ( * ( uint16_t * )( d -> config + address ));
break ;
}
/* fall through */
case 1 :
val = d -> config [ address ];
329
330
331
332
333
break ;
}
return val ;
}
ths
authored
18 years ago
334
void pci_default_write_config ( PCIDevice * d ,
335
336
337
uint32_t address , uint32_t val , int len )
{
int can_write , i ;
338
uint32_t end , addr ;
339
ths
authored
18 years ago
340
if ( len == 4 && (( address >= 0x10 && address < 0x10 + 4 * 6 ) ||
341
( address >= 0x30 && address < 0x34 ))) {
342
343
344
PCIIORegion * r ;
int reg ;
345
346
347
348
349
if ( address >= 0x30 ) {
reg = PCI_ROM_SLOT ;
} else {
reg = ( address - 0x10 ) >> 2 ;
}
350
351
352
353
r = & d -> io_regions [ reg ];
if ( r -> size == 0 )
goto default_config ;
/* compute the stored value */
354
355
356
357
358
359
360
361
if ( reg == PCI_ROM_SLOT ) {
/* keep ROM enable bit */
val &= ( ~ ( r -> size - 1 )) | 1 ;
} else {
val &= ~ ( r -> size - 1 );
val |= r -> type ;
}
* ( uint32_t * )( d -> config + address ) = cpu_to_le32 ( val );
362
pci_update_mappings ( d );
363
return ;
364
365
366
}
default_config :
/* not efficient, but simple */
367
addr = address ;
368
369
for ( i = 0 ; i < len ; i ++ ) {
/* default read/write accesses */
370
switch ( d -> config [ 0x0e ]) {
371
case 0x00 :
372
373
374
375
376
377
378
379
380
381
382
383
case 0x80 :
switch ( addr ) {
case 0x00 :
case 0x01 :
case 0x02 :
case 0x03 :
case 0x08 :
case 0x09 :
case 0x0a :
case 0x0b :
case 0x0e :
case 0x10 ... 0x27 : /* base */
384
case 0x2c ... 0x2f : /* read-only subsystem ID & vendor ID */
385
386
387
388
389
390
391
392
case 0x30 ... 0x33 : /* rom */
case 0x3d :
can_write = 0 ;
break ;
default :
can_write = 1 ;
break ;
}
393
394
break ;
default :
395
396
397
398
399
400
401
402
403
404
405
case 0x01 :
switch ( addr ) {
case 0x00 :
case 0x01 :
case 0x02 :
case 0x03 :
case 0x08 :
case 0x09 :
case 0x0a :
case 0x0b :
case 0x0e :
406
case 0x2c ... 0x2f : /* read-only subsystem ID & vendor ID */
407
408
409
410
411
412
413
414
case 0x38 ... 0x3b : /* rom */
case 0x3d :
can_write = 0 ;
break ;
default :
can_write = 1 ;
break ;
}
415
416
417
break ;
}
if ( can_write ) {
418
419
/* Mask out writes to reserved bits in registers */
switch ( addr ) {
420
421
422
case 0x05 :
val &= ~ PCI_COMMAND_RESERVED_MASK_HI ;
break ;
423
424
425
426
427
428
429
case 0x06 :
val &= ~ PCI_STATUS_RESERVED_MASK_LO ;
break ;
case 0x07 :
val &= ~ PCI_STATUS_RESERVED_MASK_HI ;
break ;
}
430
d -> config [ addr ] = val ;
431
}
ths
authored
18 years ago
432
433
if ( ++ addr > 0xff )
break ;
434
435
436
437
438
439
440
val >>= 8 ;
}
end = address + len ;
if ( end > PCI_COMMAND && address < ( PCI_COMMAND + 2 )) {
/* if the command register is modified, we must modify the mappings */
pci_update_mappings ( d );
441
442
443
}
}
444
void pci_data_write ( void * opaque , uint32_t addr , uint32_t val , int len )
445
{
446
447
448
PCIBus * s = opaque ;
PCIDevice * pci_dev ;
int config_addr , bus_num ;
ths
authored
18 years ago
449
450
451
# if defined ( DEBUG_PCI ) && 0
printf ( "pci_data_write: addr=%08x val=%08x len=%d \n " ,
452
addr , val , len );
453
# endif
454
bus_num = ( addr >> 16 ) & 0xff ;
455
456
457
while ( s && s -> bus_num != bus_num )
s = s -> next ;
if ( ! s )
458
return ;
459
pci_dev = s -> devices [( addr >> 8 ) & 0xff ];
460
461
if ( ! pci_dev )
return ;
462
config_addr = addr & 0xff ;
463
464
465
466
# if defined ( DEBUG_PCI )
printf ( "pci_config_write: %s: addr=%02x val=%08x len=%d \n " ,
pci_dev -> name , config_addr , val , len );
# endif
467
pci_dev -> config_write ( pci_dev , config_addr , val , len );
468
469
}
470
uint32_t pci_data_read ( void * opaque , uint32_t addr , int len )
471
{
472
473
474
PCIBus * s = opaque ;
PCIDevice * pci_dev ;
int config_addr , bus_num ;
475
476
uint32_t val ;
477
bus_num = ( addr >> 16 ) & 0xff ;
478
479
480
while ( s && s -> bus_num != bus_num )
s = s -> next ;
if ( ! s )
481
goto fail ;
482
pci_dev = s -> devices [( addr >> 8 ) & 0xff ];
483
484
if ( ! pci_dev ) {
fail :
485
486
487
488
489
490
491
492
493
494
495
496
switch ( len ) {
case 1 :
val = 0xff ;
break ;
case 2 :
val = 0xffff ;
break ;
default :
case 4 :
val = 0xffffffff ;
break ;
}
497
498
goto the_end ;
}
499
config_addr = addr & 0xff ;
500
501
502
503
504
505
506
507
val = pci_dev -> config_read ( pci_dev , config_addr , len );
# if defined ( DEBUG_PCI )
printf ( "pci_config_read: %s: addr=%02x val=%08x len=%d \n " ,
pci_dev -> name , config_addr , val , len );
# endif
the_end :
# if defined ( DEBUG_PCI ) && 0
printf ( "pci_data_read: addr=%08x val=%08x len=%d \n " ,
508
addr , val , len );
509
510
511
512
# endif
return val ;
}
513
514
/***********************************************************/
/* generic PCI irq support */
515
516
/* 0 <= irq_num <= 3. level must be 0 or 1 */
517
static void pci_set_irq ( void * opaque , int irq_num , int level )
518
{
519
PCIDevice * pci_dev = ( PCIDevice * ) opaque ;
520
521
PCIBus * bus ;
int change ;
ths
authored
18 years ago
522
523
524
525
change = level - pci_dev -> irq_state [ irq_num ];
if ( ! change )
return ;
526
527
pci_dev -> irq_state [ irq_num ] = level ;
528
529
for (;;) {
bus = pci_dev -> bus ;
530
irq_num = bus -> map_irq ( pci_dev , irq_num );
531
532
if ( bus -> set_irq )
break ;
533
534
535
pci_dev = bus -> parent_dev ;
}
bus -> irq_count [ irq_num ] += change ;
536
bus -> set_irq ( bus -> irq_opaque , irq_num , bus -> irq_count [ irq_num ] != 0 );
537
538
}
539
540
/***********************************************************/
/* monitor info on PCI */
541
542
543
544
545
546
typedef struct {
uint16_t class ;
const char * desc ;
} pci_class_desc ;
547
static const pci_class_desc pci_class_descriptions [] =
548
{
549
{ 0x0100 , "SCSI controller" },
550
{ 0x0101 , "IDE controller" },
ths
authored
18 years ago
551
552
553
554
555
556
{ 0x0102 , "Floppy controller" },
{ 0x0103 , "IPI controller" },
{ 0x0104 , "RAID controller" },
{ 0x0106 , "SATA controller" },
{ 0x0107 , "SAS controller" },
{ 0x0180 , "Storage controller" },
557
{ 0x0200 , "Ethernet controller" },
ths
authored
18 years ago
558
559
560
561
{ 0x0201 , "Token Ring controller" },
{ 0x0202 , "FDDI controller" },
{ 0x0203 , "ATM controller" },
{ 0x0280 , "Network controller" },
562
{ 0x0300 , "VGA controller" },
ths
authored
18 years ago
563
564
565
566
567
568
569
570
571
572
{ 0x0301 , "XGA controller" },
{ 0x0302 , "3D controller" },
{ 0x0380 , "Display controller" },
{ 0x0400 , "Video controller" },
{ 0x0401 , "Audio controller" },
{ 0x0402 , "Phone" },
{ 0x0480 , "Multimedia controller" },
{ 0x0500 , "RAM controller" },
{ 0x0501 , "Flash controller" },
{ 0x0580 , "Memory controller" },
573
574
{ 0x0600 , "Host bridge" },
{ 0x0601 , "ISA bridge" },
ths
authored
18 years ago
575
576
{ 0x0602 , "EISA bridge" },
{ 0x0603 , "MC bridge" },
577
{ 0x0604 , "PCI bridge" },
ths
authored
18 years ago
578
579
580
581
582
{ 0x0605 , "PCMCIA bridge" },
{ 0x0606 , "NUBUS bridge" },
{ 0x0607 , "CARDBUS bridge" },
{ 0x0608 , "RACEWAY bridge" },
{ 0x0680 , "Bridge" },
583
584
585
586
{ 0x0c03 , "USB controller" },
{ 0 , NULL }
};
587
static void pci_info_device ( PCIDevice * d )
588
{
589
590
int i , class ;
PCIIORegion * r ;
591
const pci_class_desc * desc ;
592
593
594
595
596
term_printf ( " Bus %2d, device %3d, function %d: \n " ,
d -> bus -> bus_num , d -> devfn >> 3 , d -> devfn & 7 );
class = le16_to_cpu ( * (( uint16_t * )( d -> config + PCI_CLASS_DEVICE )));
term_printf ( " " );
597
598
599
600
601
602
desc = pci_class_descriptions ;
while ( desc -> desc && class != desc -> class )
desc ++ ;
if ( desc -> desc ) {
term_printf ( "%s" , desc -> desc );
} else {
603
term_printf ( "Class %04x" , class );
604
}
605
606
607
term_printf ( ": PCI device %04x:%04x \n " ,
le16_to_cpu ( * (( uint16_t * )( d -> config + PCI_VENDOR_ID ))),
le16_to_cpu ( * (( uint16_t * )( d -> config + PCI_DEVICE_ID ))));
608
609
610
if ( d -> config [ PCI_INTERRUPT_PIN ] != 0 ) {
term_printf ( " IRQ %d. \n " , d -> config [ PCI_INTERRUPT_LINE ]);
611
}
612
613
614
if ( class == 0x0604 ) {
term_printf ( " BUS %d. \n " , d -> config [ 0x19 ]);
}
615
616
617
618
619
for ( i = 0 ; i < PCI_NUM_REGIONS ; i ++ ) {
r = & d -> io_regions [ i ];
if ( r -> size != 0 ) {
term_printf ( " BAR%d: " , i );
if ( r -> type & PCI_ADDRESS_SPACE_IO ) {
ths
authored
18 years ago
620
term_printf ( "I/O at 0x%04x [0x%04x]. \n " ,
621
622
r -> addr , r -> addr + r -> size - 1 );
} else {
ths
authored
18 years ago
623
term_printf ( "32 bit memory at 0x%08x [0x%08x]. \n " ,
624
625
626
r -> addr , r -> addr + r -> size - 1 );
}
}
627
}
628
629
630
if ( class == 0x0604 && d -> config [ 0x19 ] != 0 ) {
pci_for_each_device ( d -> config [ 0x19 ], pci_info_device );
}
631
632
}
633
void pci_for_each_device ( int bus_num , void ( * fn )( PCIDevice * d ))
634
{
635
PCIBus * bus = first_bus ;
636
PCIDevice * d ;
637
int devfn ;
ths
authored
18 years ago
638
639
640
while ( bus && bus -> bus_num != bus_num )
bus = bus -> next ;
641
642
643
644
645
646
if ( bus ) {
for ( devfn = 0 ; devfn < 256 ; devfn ++ ) {
d = bus -> devices [ devfn ];
if ( d )
fn ( d );
}
647
648
649
}
}
650
void pci_info ( void )
651
{
652
pci_for_each_device ( 0 , pci_info_device );
653
}
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
static const char * const pci_nic_models [] = {
"ne2k_pci" ,
"i82551" ,
"i82557b" ,
"i82559er" ,
"rtl8139" ,
"e1000" ,
"pcnet" ,
"virtio" ,
NULL
};
typedef void ( * PCINICInitFn )( PCIBus * , NICInfo * , int );
static PCINICInitFn pci_nic_init_fns [] = {
pci_ne2000_init ,
pci_i82551_init ,
pci_i82557b_init ,
pci_i82559er_init ,
pci_rtl8139_init ,
pci_e1000_init ,
pci_pcnet_init ,
virtio_net_init ,
NULL
};
681
/* Initialize a PCI NIC. */
682
683
void pci_nic_init ( PCIBus * bus , NICInfo * nd , int devfn ,
const char * default_model )
684
{
685
686
687
688
689
690
691
int i ;
qemu_check_nic_model_list ( nd , pci_nic_models , default_model );
for ( i = 0 ; pci_nic_models [ i ]; i ++ )
if ( strcmp ( nd -> model , pci_nic_models [ i ]) == 0 )
pci_nic_init_fns [ i ]( bus , nd , devfn );
692
693
}
694
695
696
697
698
typedef struct {
PCIDevice dev ;
PCIBus * bus ;
} PCIBridge ;
699
static void pci_bridge_write_config ( PCIDevice * d ,
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
uint32_t address , uint32_t val , int len )
{
PCIBridge * s = ( PCIBridge * ) d ;
if ( address == 0x19 || ( address == 0x18 && len > 1 )) {
if ( address == 0x19 )
s -> bus -> bus_num = val & 0xff ;
else
s -> bus -> bus_num = ( val >> 8 ) & 0xff ;
# if defined ( DEBUG_PCI )
printf ( "pci-bridge: %s: Assigned bus %d \n " , d -> name , s -> bus -> bus_num );
# endif
}
pci_default_write_config ( d , address , val , len );
}
716
PCIBus * pci_bridge_init ( PCIBus * bus , int devfn , uint16_t vid , uint16_t did ,
717
718
719
pci_map_irq_fn map_irq , const char * name )
{
PCIBridge * s ;
ths
authored
18 years ago
720
s = ( PCIBridge * ) pci_register_device ( bus , name , sizeof ( PCIBridge ),
721
devfn , NULL , pci_bridge_write_config );
722
723
724
725
pci_config_set_vendor_id ( s -> dev . config , vid );
pci_config_set_device_id ( s -> dev . config , did );
726
727
728
729
730
731
s -> dev . config [ 0x04 ] = 0x06 ; // command = bus master , pci mem
s -> dev . config [ 0x05 ] = 0x00 ;
s -> dev . config [ 0x06 ] = 0xa0 ; // status = fast back - to - back , 66 MHz , no error
s -> dev . config [ 0x07 ] = 0x00 ; // status = fast devsel
s -> dev . config [ 0x08 ] = 0x00 ; // revision
s -> dev . config [ 0x09 ] = 0x00 ; // programming i / f
732
pci_config_set_class ( s -> dev . config , PCI_CLASS_BRIDGE_PCI );
733
734
735
736
737
738
739
s -> dev . config [ 0x0D ] = 0x10 ; // latency_timer
s -> dev . config [ 0x0E ] = 0x81 ; // header_type
s -> dev . config [ 0x1E ] = 0xa0 ; // secondary status
s -> bus = pci_register_secondary_bus ( & s -> dev , map_irq );
return s -> bus ;
}