2 Copyright © 2004-2012, The AROS Development Team. All rights reserved.
9 #include <exec/types.h>
12 #include <utility/tagitem.h>
13 #include <proto/exec.h>
14 #include <proto/utility.h>
15 #include <proto/oop.h>
20 #include <aros/debug.h>
22 #undef HiddPCIDeviceAttrBase
23 #define HiddPCIDeviceAttrBase (PSD(cl)->hiddPCIDeviceAB)
24 #undef HiddPCIDriverAttrBase
25 #define HiddPCIDriverAttrBase (PSD(cl)->hiddPCIDriverAB)
27 static void setLong(OOP_Class
*cl
, OOP_Object
*o
, ULONG reg
, ULONG value
)
29 tDeviceData
*dev
= (tDeviceData
*)OOP_INST_DATA(cl
,o
);
30 OOP_Object
*driver
= dev
->driver
;
32 struct pHidd_PCIDriver_WriteConfigLong msg
;
34 msg
.mID
= PSD(cl
)->mid_WL
;
41 OOP_DoMethod(driver
, (OOP_Msg
)&msg
);
44 static void setWord(OOP_Class
*cl
, OOP_Object
*o
, ULONG reg
, UWORD value
)
46 tDeviceData
*dev
= (tDeviceData
*)OOP_INST_DATA(cl
,o
);
47 OOP_Object
*driver
= dev
->driver
;
49 struct pHidd_PCIDriver_WriteConfigWord msg
;
51 msg
.mID
= PSD(cl
)->mid_WW
;
58 OOP_DoMethod(driver
, (OOP_Msg
)&msg
);
61 static void setByte(OOP_Class
*cl
, OOP_Object
*o
, ULONG reg
, UBYTE value
)
63 tDeviceData
*dev
= (tDeviceData
*)OOP_INST_DATA(cl
,o
);
64 OOP_Object
*driver
= dev
->driver
;
66 struct pHidd_PCIDriver_WriteConfigByte msg
;
68 msg
.mID
= PSD(cl
)->mid_WB
;
75 OOP_DoMethod(driver
, (OOP_Msg
)&msg
);
78 static ULONG
getLong(OOP_Class
*cl
, OOP_Object
*o
, ULONG reg
)
80 tDeviceData
*dev
= (tDeviceData
*)OOP_INST_DATA(cl
,o
);
81 OOP_Object
*driver
= dev
->driver
;
83 struct pHidd_PCIDriver_ReadConfigLong msg
;
85 msg
.mID
= PSD(cl
)->mid_RL
;
91 return OOP_DoMethod(driver
, (OOP_Msg
)&msg
);
94 static UWORD
getWord(OOP_Class
*cl
, OOP_Object
*o
, ULONG reg
)
96 tDeviceData
*dev
= (tDeviceData
*)OOP_INST_DATA(cl
,o
);
97 OOP_Object
*driver
= dev
->driver
;
99 struct pHidd_PCIDriver_ReadConfigWord msg
;
101 msg
.mID
= PSD(cl
)->mid_RW
;
107 return OOP_DoMethod(driver
, (OOP_Msg
)&msg
);
110 static UBYTE
getByte(OOP_Class
*cl
, OOP_Object
*o
, ULONG reg
)
112 tDeviceData
*dev
= (tDeviceData
*)OOP_INST_DATA(cl
,o
);
113 OOP_Object
*driver
= dev
->driver
;
115 struct pHidd_PCIDriver_ReadConfigByte msg
;
117 msg
.mID
= PSD(cl
)->mid_RB
;
123 return OOP_DoMethod(driver
, (OOP_Msg
)&msg
);
126 /* Returns offset of capability area in config area or 0 of capability is not present */
127 static UBYTE
findCapabilityOffset(OOP_Class
* cl
, OOP_Object
*o
, UBYTE capability
)
129 UWORD where
= 0x34; /* First cap list entry */
132 /* Check if capabilities present at all */
133 if ((getWord(cl
, o
, PCICS_STATUS
) & PCISTF_CAPABILITIES
) != PCISTF_CAPABILITIES
)
136 /* Iterate over capabilities */
139 where
= getByte(cl
, o
, where
);
145 capid
= getByte(cl
, o
, where
);
150 if (capid
== capability
) return (UBYTE
)where
;
152 where
+= 1; /* next cap */
158 UBYTE
PCIDev__Hidd_PCIDevice__ReadConfigByte(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_PCIDevice_ReadConfigByte
*msg
)
160 return getByte(cl
, o
, msg
->reg
);
163 UWORD
PCIDev__Hidd_PCIDevice__ReadConfigWord(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_PCIDevice_ReadConfigWord
*msg
)
165 return getWord(cl
, o
, msg
->reg
);
168 ULONG
PCIDev__Hidd_PCIDevice__ReadConfigLong(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_PCIDevice_ReadConfigLong
*msg
)
170 return getLong(cl
, o
, msg
->reg
);
173 VOID
PCIDev__Hidd_PCIDevice__WriteConfigByte(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_PCIDevice_WriteConfigByte
*msg
)
175 setByte(cl
, o
, msg
->reg
, msg
->val
);
178 VOID
PCIDev__Hidd_PCIDevice__WriteConfigWord(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_PCIDevice_WriteConfigWord
*msg
)
180 setWord(cl
, o
, msg
->reg
, msg
->val
);
183 VOID
PCIDev__Hidd_PCIDevice__WriteConfigLong(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_PCIDevice_WriteConfigLong
*msg
)
185 setLong(cl
, o
, msg
->reg
, msg
->val
);
190 PCIDevice::New method is invoked by base pci class. It passes to the device
191 class information about the driver this class should use and location of
192 created device on the PCI bus handled by given driver.
194 OOP_Object
*PCIDev__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
198 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
) msg
);
201 struct TagItem
*tag
, *tags
;
202 tDeviceData
*dev
= (tDeviceData
*)OOP_INST_DATA(cl
, o
);
203 OOP_Object
*driver
= NULL
;
205 tags
=(struct TagItem
*)msg
->attrList
;
208 Get all information passed by pci class calling OOP_NewObject()
210 while((tag
= NextTagItem(&tags
)))
214 if (IS_PCIDEV_ATTR(tag
->ti_Tag
, idx
))
218 case aoHidd_PCIDevice_Driver
:
219 dev
->driver
= (OOP_Object
*)tag
->ti_Data
;
220 driver
= dev
->driver
;
223 case aoHidd_PCIDevice_Bus
:
224 dev
->bus
= tag
->ti_Data
;
227 case aoHidd_PCIDevice_Dev
:
228 dev
->dev
= tag
->ti_Data
;
231 case aoHidd_PCIDevice_Sub
:
232 dev
->sub
= tag
->ti_Data
;
239 If driver is passed (*HAS TO* be passed) acquire some unchangeable
240 information regarding given device
247 Get the header type in order to determine whether it is a
250 ht
= getByte(cl
, o
, PCICS_HEADERTYPE
) & PCIHT_MASK
;
252 if (ht
== PCIHT_BRIDGE
)
255 dev
->subbus
= getByte(cl
, o
, PCIBR_SUBBUS
);
258 /* Get all constant ID's */
259 dev
->VendorID
= getWord(cl
, o
, PCICS_VENDOR
);
260 dev
->ProductID
= getWord(cl
, o
, PCICS_PRODUCT
);
262 dev
->RevisionID
= getByte(cl
, o
, PCICS_REVISION
);
263 dev
->Interface
= getByte(cl
, o
, PCICS_PROGIF
);
264 dev
->SubClass
= getByte(cl
, o
, PCICS_SUBCLASS
);
265 dev
->Class
= getByte(cl
, o
, PCICS_CLASS
);
267 dev
->SubsysVID
= getWord(cl
, o
, PCICS_SUBVENDOR
);
268 dev
->SubsystemID
= getWord(cl
, o
, PCICS_SUBSYSTEM
);
270 dev
->IRQLine
= getByte(cl
, o
, PCICS_INT_PIN
);
274 dev
->INTLine
= getByte(cl
, o
, PCICS_INT_LINE
);
276 else dev
->INTLine
= 0;
278 dev
->HeaderType
= ht
;
280 getPCIClassDesc(dev
->Class
, dev
->SubClass
, dev
->Interface
,
281 &dev
->strClass
, &dev
->strSubClass
, &dev
->strInterface
);
283 /* Satisfy BUG watchers ;) */
284 D(bug("[PCIDevice] %02x.%02x.%x = %04.4lx:%04.4lx (%s %s %s)\n",
285 dev
->bus
, dev
->dev
, dev
->sub
,
286 dev
->VendorID
, dev
->ProductID
,
287 dev
->strClass
, dev
->strSubClass
, dev
->strInterface
));
288 D(bug("[PCIDevice] > IRQ %u INT %u\n", dev
->IRQLine
, dev
->INTLine
));
290 // print out a warning to the user in case the interrupt line is not assigned by BIOS
291 if (dev
->INTLine
== 255 && !dev
->isBridge
)
292 bug("[PCIDevice] WARNING: Interrupt line is not assigned! Device may freeze or malfunction at use!\n");
294 /* Read two first base addresses */
295 for (i
= 0; i
< 2; i
++)
297 dev
->BaseReg
[i
].addr
= getLong(cl
, o
, PCICS_BAR0
+ (i
<< 2));
298 dev
->BaseReg
[i
].size
= sizePCIBaseReg(driver
, PSD(cl
), dev
->bus
,
299 dev
->dev
, dev
->sub
, i
);
302 /* Address and size of ROM */
303 dev
->RomBase
= getLong(cl
, o
, PCICS_EXPROM_BASE
);
304 dev
->RomSize
= sizePCIBaseReg(driver
, PSD(cl
), dev
->bus
,
305 dev
->dev
, dev
->sub
, (PCICS_EXPROM_BASE
- PCICS_BAR0
) >> 2);
308 Bridges specify only first two base addresses. If not bridge,
313 for (i
= 2; i
< 6; i
++)
315 dev
->BaseReg
[i
].addr
= getLong(cl
, o
, PCICS_BAR0
+ (i
<< 2));
316 dev
->BaseReg
[i
].size
= sizePCIBaseReg(driver
, PSD(cl
), dev
->bus
,
317 dev
->dev
, dev
->sub
, i
);
327 PCIDevice::Get method splitted into few parts in order to make switch'es shorter.
330 static void dispatch_generic(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
333 tDeviceData
*dev
= (tDeviceData
*)OOP_INST_DATA(cl
,o
);
335 idx
= msg
->attrID
- HiddPCIDeviceAttrBase
;
339 case aoHidd_PCIDevice_Driver
:
340 *msg
->storage
= (IPTR
)dev
->driver
;
343 case aoHidd_PCIDevice_Bus
:
344 *msg
->storage
= (IPTR
)dev
->bus
;
347 case aoHidd_PCIDevice_Dev
:
348 *msg
->storage
= (IPTR
)dev
->dev
;
351 case aoHidd_PCIDevice_Sub
:
352 *msg
->storage
= (IPTR
)dev
->sub
;
355 case aoHidd_PCIDevice_VendorID
:
356 *msg
->storage
= (IPTR
)dev
->VendorID
;
359 case aoHidd_PCIDevice_ProductID
:
360 *msg
->storage
= (IPTR
)dev
->ProductID
;
363 case aoHidd_PCIDevice_RevisionID
:
364 *msg
->storage
= (IPTR
)dev
->RevisionID
;
367 case aoHidd_PCIDevice_Interface
:
368 *msg
->storage
= (IPTR
)dev
->Interface
;
371 case aoHidd_PCIDevice_Class
:
372 *msg
->storage
= (IPTR
)dev
->Class
;
375 case aoHidd_PCIDevice_SubClass
:
376 *msg
->storage
= (IPTR
)dev
->SubClass
;
379 case aoHidd_PCIDevice_SubsystemVendorID
:
380 *msg
->storage
= (IPTR
)dev
->SubsysVID
;
383 case aoHidd_PCIDevice_SubsystemID
:
384 *msg
->storage
= (IPTR
)dev
->SubsystemID
;
387 case aoHidd_PCIDevice_INTLine
:
388 *msg
->storage
= (IPTR
)dev
->INTLine
;
391 case aoHidd_PCIDevice_IRQLine
:
392 *msg
->storage
= (IPTR
)dev
->IRQLine
;
395 case aoHidd_PCIDevice_RomBase
:
396 *msg
->storage
= (IPTR
)dev
->RomBase
;
399 case aoHidd_PCIDevice_RomSize
:
400 *msg
->storage
= (IPTR
)dev
->RomSize
;
405 static void dispatch_base(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
408 tDeviceData
*dev
= (tDeviceData
*)OOP_INST_DATA(cl
,o
);
410 idx
= msg
->attrID
- HiddPCIDeviceAttrBase
;
415 case aoHidd_PCIDevice_Base0
: id
= 0; break;
416 case aoHidd_PCIDevice_Base1
: id
= 1; break;
417 case aoHidd_PCIDevice_Base2
: id
= 2; break;
418 case aoHidd_PCIDevice_Base3
: id
= 3; break;
419 case aoHidd_PCIDevice_Base4
: id
= 4; break;
420 case aoHidd_PCIDevice_Base5
: id
= 5; break;
423 /* Do not allow reading of more than two base addresses in case of PCI-PCI bridges */
424 if (dev
->isBridge
&& id
>= 2) { *msg
->storage
= 0; return; }
426 *msg
->storage
= (IPTR
)dev
->BaseReg
[id
].addr
;
427 if ((dev
->BaseReg
[id
].addr
& PCIBAR_MASK_TYPE
)==PCIBAR_TYPE_IO
)
430 *msg
->storage
&= PCIBAR_MASK_IO
;
431 OOP_GetAttr(dev
->driver
, aHidd_PCIDriver_IOBase
, &IOBase
);
432 *msg
->storage
+= IOBase
;
436 *msg
->storage
&= PCIBAR_MASK_MEM
;
440 static void dispatch_type(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
443 tDeviceData
*dev
= (tDeviceData
*)OOP_INST_DATA(cl
,o
);
445 idx
= msg
->attrID
- HiddPCIDeviceAttrBase
;
450 case aoHidd_PCIDevice_Type0
: id
= 0; break;
451 case aoHidd_PCIDevice_Type1
: id
= 1; break;
452 case aoHidd_PCIDevice_Type2
: id
= 2; break;
453 case aoHidd_PCIDevice_Type3
: id
= 3; break;
454 case aoHidd_PCIDevice_Type4
: id
= 4; break;
455 case aoHidd_PCIDevice_Type5
: id
= 5; break;
458 /* Do not allow reading of more than two base addresses in case of PCI-PCI bridges */
459 if (dev
->isBridge
&& id
>= 2) { *msg
->storage
= 0; return; }
461 *msg
->storage
= (IPTR
)dev
->BaseReg
[id
].addr
;
462 if ((dev
->BaseReg
[id
].addr
& PCIBAR_MASK_TYPE
)==PCIBAR_TYPE_IO
)
464 *msg
->storage
&= ~PCIBAR_MASK_IO
;
468 *msg
->storage
&= ~PCIBAR_MASK_MEM
;
472 static void dispatch_size(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
475 tDeviceData
*dev
= (tDeviceData
*)OOP_INST_DATA(cl
,o
);
477 idx
= msg
->attrID
- HiddPCIDeviceAttrBase
;
482 case aoHidd_PCIDevice_Size0
: id
= 0; break;
483 case aoHidd_PCIDevice_Size1
: id
= 1; break;
484 case aoHidd_PCIDevice_Size2
: id
= 2; break;
485 case aoHidd_PCIDevice_Size3
: id
= 3; break;
486 case aoHidd_PCIDevice_Size4
: id
= 4; break;
487 case aoHidd_PCIDevice_Size5
: id
= 5; break;
490 /* Do not allow reading of more than two base addresses in case of PCI-PCI bridges */
491 if (dev
->isBridge
&& id
>= 2) { *msg
->storage
= 0; return;}
493 *msg
->storage
= (IPTR
)dev
->BaseReg
[id
].size
;
496 static void dispatch_pci2pcibridge(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
499 tDeviceData
*dev
= (tDeviceData
*)OOP_INST_DATA(cl
,o
);
503 /* If device is not a PCI-PCI bridge, do nothing */
504 if (!dev
->isBridge
) { *msg
->storage
= 0; return; }
506 control
= getWord(cl
, o
, PCIBR_CONTROL
);
508 idx
= msg
->attrID
- HiddPCIDeviceAttrBase
;
512 case aoHidd_PCIDevice_isBridge
:
513 *msg
->storage
= dev
->isBridge
;
516 case aoHidd_PCIDevice_SubBus
:
517 *msg
->storage
= dev
->subbus
;
520 case aoHidd_PCIDevice_MemoryBase
:
521 *msg
->storage
= getWord(cl
, o
, PCIBR_MEMBASE
) << 16;
524 case aoHidd_PCIDevice_MemoryLimit
:
525 *msg
->storage
= getWord(cl
, o
, PCIBR_MEMLIMIT
) << 16;
528 case aoHidd_PCIDevice_PrefetchableBase
:
529 *msg
->storage
= getWord(cl
, o
, PCIBR_PREFETCHBASE
) << 16;
532 case aoHidd_PCIDevice_PrefetchableLimit
:
533 *msg
->storage
= getWord(cl
, o
, PCIBR_PREFETCHLIMIT
) << 16;
536 case aoHidd_PCIDevice_IOBase
:
537 *msg
->storage
= getByte(cl
, o
, PCIBR_IOBASE
) << 8;
540 case aoHidd_PCIDevice_IOLimit
:
541 *msg
->storage
= getByte(cl
, o
, PCIBR_IOLIMIT
) << 8;
544 case aoHidd_PCIDevice_ISAEnable
:
545 *msg
->storage
= (control
& PCICTRLF_ISAENABLE
) == PCICTRLF_ISAENABLE
;
548 case aoHidd_PCIDevice_VGAEnable
:
549 *msg
->storage
= (control
& PCICTRLF_VGAENABLE
) == PCICTRLF_VGAENABLE
;
554 static void dispatch_capability(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
557 UBYTE capability
= 0;
558 //tDeviceData *dev = (tDeviceData *)OOP_INST_DATA(cl,o);
560 idx
= msg
->attrID
- HiddPCIDeviceAttrBase
;
564 case aoHidd_PCIDevice_CapabilityPowerManagement
: capability
= PCICAP_POWER_MANAGEMENT
;break;
565 case aoHidd_PCIDevice_CapabilityAGP
: capability
= PCICAP_AGP
;break;
566 case aoHidd_PCIDevice_CapabilityVitalProductData
: capability
= PCICAP_VITAL_PRODUCT_DATA
;break;
567 case aoHidd_PCIDevice_CapabilitySlotID
: capability
= PCICAP_SLOT_ID
;break;
568 case aoHidd_PCIDevice_CapabilityMSI
: capability
= PCICAP_MSI
;break;
569 case aoHidd_PCIDevice_CapabilityCPCIHotSwap
: capability
= PCICAP_CPCI_HOT_SWAP
;break;
570 case aoHidd_PCIDevice_CapabilityPCIX
: capability
= PCICAP_PCIX
;break;
571 case aoHidd_PCIDevice_CapabilityHyperTransport
: capability
= PCICAP_HYPER_TRANSPORT
;break;
572 case aoHidd_PCIDevice_CapabilityVendorSpecific
: capability
= PCICAP_VENDOR_SPECIFIC
;break;
573 case aoHidd_PCIDevice_CapabilityDebugPort
: capability
= PCICAP_DEBUG_PORT
;break;
574 case aoHidd_PCIDevice_CapabilityCPCICRC
: capability
= PCICAP_CPCI_CR
;break;
575 case aoHidd_PCIDevice_CapabilityHotPlugController
: capability
= PCICAP_HOT_PLUG_CONTROLLER
;break;
576 case aoHidd_PCIDevice_CapabilitySSVPID
: capability
= PCICAP_SSVPID
;break;
577 case aoHidd_PCIDevice_CapabilityAGP3
: capability
= PCICAP_AGP3
;break;
578 case aoHidd_PCIDevice_CapabilityPCIE
: capability
= PCICAP_PCIE
;break;
579 case aoHidd_PCIDevice_CapabilityMSIX
: capability
= PCICAP_MSIX
;break;
580 case aoHidd_PCIDevice_CapabilityAdvancedFeatures
: capability
= PCICAP_ADVANCED_FEATURES
;break;
583 *msg
->storage
= findCapabilityOffset(cl
, o
, capability
);
586 typedef void (*dispatcher_t
)(OOP_Class
*, OOP_Object
*, struct pRoot_Get
*);
588 static const dispatcher_t Dispatcher
[num_Hidd_PCIDevice_Attrs
] =
590 [aoHidd_PCIDevice_Driver
] = dispatch_generic
,
591 [aoHidd_PCIDevice_Bus
] = dispatch_generic
,
592 [aoHidd_PCIDevice_Dev
] = dispatch_generic
,
593 [aoHidd_PCIDevice_Sub
] = dispatch_generic
,
594 [aoHidd_PCIDevice_VendorID
] = dispatch_generic
,
595 [aoHidd_PCIDevice_ProductID
] = dispatch_generic
,
596 [aoHidd_PCIDevice_RevisionID
] = dispatch_generic
,
597 [aoHidd_PCIDevice_Interface
] = dispatch_generic
,
598 [aoHidd_PCIDevice_Class
] = dispatch_generic
,
599 [aoHidd_PCIDevice_SubClass
] = dispatch_generic
,
600 [aoHidd_PCIDevice_SubsystemVendorID
] = dispatch_generic
,
601 [aoHidd_PCIDevice_SubsystemID
] = dispatch_generic
,
602 [aoHidd_PCIDevice_INTLine
] = dispatch_generic
,
603 [aoHidd_PCIDevice_IRQLine
] = dispatch_generic
,
604 [aoHidd_PCIDevice_RomBase
] = dispatch_generic
,
605 [aoHidd_PCIDevice_RomSize
] = dispatch_generic
,
606 [aoHidd_PCIDevice_Base0
] = dispatch_base
,
607 [aoHidd_PCIDevice_Base1
] = dispatch_base
,
608 [aoHidd_PCIDevice_Base2
] = dispatch_base
,
609 [aoHidd_PCIDevice_Base3
] = dispatch_base
,
610 [aoHidd_PCIDevice_Base4
] = dispatch_base
,
611 [aoHidd_PCIDevice_Base5
] = dispatch_base
,
612 [aoHidd_PCIDevice_Size0
] = dispatch_size
,
613 [aoHidd_PCIDevice_Size1
] = dispatch_size
,
614 [aoHidd_PCIDevice_Size2
] = dispatch_size
,
615 [aoHidd_PCIDevice_Size3
] = dispatch_size
,
616 [aoHidd_PCIDevice_Size4
] = dispatch_size
,
617 [aoHidd_PCIDevice_Size5
] = dispatch_size
,
618 [aoHidd_PCIDevice_Type0
] = dispatch_type
,
619 [aoHidd_PCIDevice_Type1
] = dispatch_type
,
620 [aoHidd_PCIDevice_Type2
] = dispatch_type
,
621 [aoHidd_PCIDevice_Type3
] = dispatch_type
,
622 [aoHidd_PCIDevice_Type4
] = dispatch_type
,
623 [aoHidd_PCIDevice_Type5
] = dispatch_type
,
625 /* Bridge attributes */
626 [aoHidd_PCIDevice_isBridge
] = dispatch_pci2pcibridge
,
627 [aoHidd_PCIDevice_SubBus
] = dispatch_pci2pcibridge
,
628 [aoHidd_PCIDevice_MemoryBase
] = dispatch_pci2pcibridge
,
629 [aoHidd_PCIDevice_MemoryLimit
] = dispatch_pci2pcibridge
,
630 [aoHidd_PCIDevice_PrefetchableBase
] = dispatch_pci2pcibridge
,
631 [aoHidd_PCIDevice_PrefetchableLimit
] = dispatch_pci2pcibridge
,
632 [aoHidd_PCIDevice_IOBase
] = dispatch_pci2pcibridge
,
633 [aoHidd_PCIDevice_IOLimit
] = dispatch_pci2pcibridge
,
634 [aoHidd_PCIDevice_ISAEnable
] = dispatch_pci2pcibridge
,
635 [aoHidd_PCIDevice_VGAEnable
] = dispatch_pci2pcibridge
,
638 [aoHidd_PCIDevice_CapabilityPowerManagement
] = dispatch_capability
,
639 [aoHidd_PCIDevice_CapabilityAGP
] = dispatch_capability
,
640 [aoHidd_PCIDevice_CapabilityVitalProductData
] = dispatch_capability
,
641 [aoHidd_PCIDevice_CapabilitySlotID
] = dispatch_capability
,
642 [aoHidd_PCIDevice_CapabilityMSI
] = dispatch_capability
,
643 [aoHidd_PCIDevice_CapabilityCPCIHotSwap
] = dispatch_capability
,
644 [aoHidd_PCIDevice_CapabilityPCIX
] = dispatch_capability
,
645 [aoHidd_PCIDevice_CapabilityHyperTransport
] = dispatch_capability
,
646 [aoHidd_PCIDevice_CapabilityVendorSpecific
] = dispatch_capability
,
647 [aoHidd_PCIDevice_CapabilityDebugPort
] = dispatch_capability
,
648 [aoHidd_PCIDevice_CapabilityCPCICRC
] = dispatch_capability
,
649 [aoHidd_PCIDevice_CapabilityHotPlugController
] = dispatch_capability
,
650 [aoHidd_PCIDevice_CapabilitySSVPID
] = dispatch_capability
,
651 [aoHidd_PCIDevice_CapabilityAGP3
] = dispatch_capability
,
652 [aoHidd_PCIDevice_CapabilityPCIE
] = dispatch_capability
,
653 [aoHidd_PCIDevice_CapabilityMSIX
] = dispatch_capability
,
654 [aoHidd_PCIDevice_CapabilityAdvancedFeatures
] = dispatch_capability
,
657 void PCIDev__Root__Get(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
660 tDeviceData
*dev
= (tDeviceData
*)OOP_INST_DATA(cl
,o
);
662 if (IS_PCIDEV_ATTR(msg
->attrID
, idx
))
664 if (Dispatcher
[idx
] != NULL
)
665 Dispatcher
[idx
](cl
, o
, msg
);
668 case aoHidd_PCIDevice_isMEM
:
670 (getWord(cl
, o
, PCICS_COMMAND
) &
672 == PCICMF_MEMDECODE
);
675 case aoHidd_PCIDevice_isIO
:
677 (getWord(cl
, o
, PCICS_COMMAND
) &
682 case aoHidd_PCIDevice_isMaster
:
684 (getWord(cl
, o
, PCICS_COMMAND
) &
686 == PCICMF_BUSMASTER
);
689 case aoHidd_PCIDevice_paletteSnoop
:
691 (getWord(cl
, o
, PCICS_COMMAND
) &
696 case aoHidd_PCIDevice_is66MHz
:
698 (getWord(cl
, o
, PCICS_STATUS
) &
703 case aoHidd_PCIDevice_ClassDesc
:
704 *msg
->storage
= (IPTR
)dev
->strClass
;
707 case aoHidd_PCIDevice_SubClassDesc
:
708 *msg
->storage
= (IPTR
)dev
->strSubClass
;
711 case aoHidd_PCIDevice_InterfaceDesc
:
712 *msg
->storage
= (IPTR
)dev
->strInterface
;
714 case aoHidd_PCIDevice_IRQStatus
:
716 (getWord(cl
, o
, PCICS_STATUS
) &
717 PCISTF_INTERRUPT_STATUS
)
718 == PCISTF_INTERRUPT_STATUS
);
720 case aoHidd_PCIDevice_CapabilitiesPresent
:
722 (getWord(cl
, o
, PCICS_STATUS
) &
724 == PCISTF_CAPABILITIES
);
728 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
) msg
);
734 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
) msg
);
738 void PCIDev__Root__Set(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Set
*msg
)
741 tDeviceData
*dev
= (tDeviceData
*)OOP_INST_DATA(cl
,o
);
742 struct TagItem
*tag
, *tags
;
744 tags
= (struct TagItem
*)msg
->attrList
;
746 while ((tag
= NextTagItem(&tags
)))
748 if (IS_PCIDEV_ATTR(tag
->ti_Tag
, idx
))
752 case aoHidd_PCIDevice_Base0
:
753 setLong(cl
, o
, PCICS_BAR0
, tag
->ti_Data
);
754 dev
->BaseReg
[0].addr
= getLong(cl
, o
, PCICS_BAR0
);
757 case aoHidd_PCIDevice_Base1
:
758 setLong(cl
, o
, PCICS_BAR1
, tag
->ti_Data
);
759 dev
->BaseReg
[1].addr
= getLong(cl
, o
, PCICS_BAR1
);
762 case aoHidd_PCIDevice_Base2
:
765 setLong(cl
, o
, PCICS_BAR2
, tag
->ti_Data
);
766 dev
->BaseReg
[2].addr
= getLong(cl
, o
, PCICS_BAR2
);
770 case aoHidd_PCIDevice_Base3
:
773 setLong(cl
, o
, PCICS_BAR3
, tag
->ti_Data
);
774 dev
->BaseReg
[3].addr
= getLong(cl
, o
, PCICS_BAR3
);
778 case aoHidd_PCIDevice_Base4
:
781 setLong(cl
, o
, PCICS_BAR4
, tag
->ti_Data
);
782 dev
->BaseReg
[4].addr
= getLong(cl
, o
, PCICS_BAR4
);
786 case aoHidd_PCIDevice_Base5
:
789 setLong(cl
, o
, PCICS_BAR5
, tag
->ti_Data
);
790 dev
->BaseReg
[5].addr
= getLong(cl
, o
, PCICS_BAR5
);
794 case aoHidd_PCIDevice_RomBase
:
795 setLong(cl
, o
, PCICS_EXPROM_BASE
, tag
->ti_Data
);
796 dev
->RomBase
= getLong(cl
, o
, PCICS_EXPROM_BASE
);
799 case aoHidd_PCIDevice_MemoryBase
:
800 if (dev
->isBridge
) setWord(cl
, o
, PCIBR_MEMBASE
, tag
->ti_Data
>> 16); break;
802 case aoHidd_PCIDevice_MemoryLimit
:
803 if (dev
->isBridge
) setWord(cl
, o
, PCIBR_MEMLIMIT
, tag
->ti_Data
>> 16); break;
805 case aoHidd_PCIDevice_PrefetchableBase
:
806 if (dev
->isBridge
) setWord(cl
, o
, PCIBR_PREFETCHBASE
, tag
->ti_Data
>> 16); break;
808 case aoHidd_PCIDevice_PrefetchableLimit
:
809 if (dev
->isBridge
) setWord(cl
, o
, PCIBR_PREFETCHLIMIT
, tag
->ti_Data
>> 16); break;
811 case aoHidd_PCIDevice_IOBase
:
812 if (dev
->isBridge
) setByte(cl
, o
, PCIBR_IOBASE
, tag
->ti_Data
>> 8); break;
814 case aoHidd_PCIDevice_IOLimit
:
815 if (dev
->isBridge
) setByte(cl
, o
, PCIBR_IOLIMIT
, tag
->ti_Data
>> 8); break;
817 case aoHidd_PCIDevice_isIO
:
819 UWORD command
= getWord(cl
, o
, PCICS_COMMAND
) & ~PCICMF_IODECODE
;
821 command
|= PCICMF_IODECODE
;
822 setWord(cl
, o
, PCICS_COMMAND
, command
);
826 case aoHidd_PCIDevice_isMEM
:
828 UWORD command
= getWord(cl
, o
, PCICS_COMMAND
) & ~PCICMF_MEMDECODE
;
830 command
|= PCICMF_MEMDECODE
;
831 setWord(cl
, o
, PCICS_COMMAND
, command
);
835 case aoHidd_PCIDevice_isMaster
:
837 UWORD command
= getWord(cl
, o
, PCICS_COMMAND
) & ~PCICMF_BUSMASTER
;
839 command
|= PCICMF_BUSMASTER
;
840 setWord(cl
, o
, PCICS_COMMAND
, command
);
844 case aoHidd_PCIDevice_paletteSnoop
:
846 UWORD command
= getWord(cl
, o
, PCICS_COMMAND
) & ~PCICMF_VGASNOOP
;
848 command
|= PCICMF_VGASNOOP
;
849 setWord(cl
, o
, PCICS_COMMAND
, command
);
853 case aoHidd_PCIDevice_ISAEnable
:
856 UWORD control
= getWord(cl
, o
, PCIBR_CONTROL
) & ~PCICTRLF_ISAENABLE
;
858 control
|= PCICTRLF_ISAENABLE
;
859 setWord(cl
, o
, PCIBR_CONTROL
, control
);
863 case aoHidd_PCIDevice_VGAEnable
:
866 UWORD control
= getWord(cl
, o
, PCIBR_CONTROL
) & ~PCICTRLF_VGAENABLE
;
868 control
|= PCICTRLF_VGAENABLE
;
869 setWord(cl
, o
, PCIBR_CONTROL
, control
);
874 bug("[PCIDevice] Trying to set nonsettable attribute %d!\n", idx
);