2 Copyright © 2004-2006, The AROS Development Team. All rights reserved.
5 Desc: PCI direct driver for i386 native.
9 #define __OOP_NOATTRBASES__
11 #include <exec/types.h>
15 #include <utility/tagitem.h>
17 #include <proto/exec.h>
18 #include <proto/utility.h>
19 #include <proto/oop.h>
21 #include <resources/processor.h>
22 #include <proto/processor.h>
24 #include <aros/symbolsets.h>
25 #include <asm/amcc440.h>
31 #include <aros/debug.h>
33 #undef HiddPCIDriverAttrBase
36 #define HiddPCIDriverAttrBase (PSD(cl)->hiddPCIDriverAB)
37 #define HiddAttrBase (PSD(cl)->hiddAB)
39 #define CFGADD(bus,dev,func,reg) \
40 ( psd->CfgBase | ((bus)<<16) | \
41 ((dev)<<11) | ((func)<<8) | ((reg)&~3))
51 We overload the New method in order to introduce the Hidd Name and
52 HardwareName attributes.
54 OOP_Object
*PCI440__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
56 struct pRoot_New mymsg
;
58 struct TagItem mytags
[] = {
59 { aHidd_Name
, (IPTR
)"PCINative" },
60 { aHidd_HardwareName
, (IPTR
)"AMCC440 native direct access PCI driver" },
61 { aHidd_PCIDriver_IOBase
, PCI0_IO
},
66 mymsg
.attrList
= (struct TagItem
*)&mytags
[0];
70 mytags
[3].ti_Tag
= TAG_MORE
;
71 mytags
[3].ti_Data
= (IPTR
)msg
->attrList
;
76 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
81 static ULONG
ReadConfigLong(struct pci_staticdata
*psd
, UBYTE bus
, UBYTE dev
, UBYTE sub
, UWORD reg
)
86 outl_le(CFGADD(bus
, dev
, sub
, reg
),PCI0_CFGADDR
);
87 temp
=inl_le(PCI0_CFGDATA
);
90 /* FIXME: Is this really needed on SAM460? Other OSes do not seem to confirm this. */
91 if (reg
== 0x3c && psd
->IntLine
!= 0xff) { /* PCICS_INT_LINE */
96 DB2(bug("[PCI440] -> %08x = %08x\n", CFGADD(bus
, dev
, sub
, reg
), temp
));
101 ULONG
PCI440__Hidd_PCIDriver__ReadConfigLong(OOP_Class
*cl
, OOP_Object
*o
,
102 struct pHidd_PCIDriver_ReadConfigLong
*msg
)
104 return ReadConfigLong(PSD(cl
), msg
->bus
, msg
->dev
, msg
->sub
, msg
->reg
);
107 static void WriteConfigLong(struct pci_staticdata
*psd
, UBYTE bus
, UBYTE dev
, UBYTE sub
, UWORD reg
, ULONG val
)
109 DB2(bug("[PCI440] <- %08x = %08x\n", CFGADD(bus
, dev
, sub
, reg
), val
));
111 outl_le(CFGADD(bus
, dev
, sub
, reg
),PCI0_CFGADDR
);
112 outl_le(val
,PCI0_CFGDATA
);
116 void PCI440__Hidd_PCIDriver__WriteConfigLong(OOP_Class
*cl
, OOP_Object
*o
,
117 struct pHidd_PCIDriver_WriteConfigLong
*msg
)
119 WriteConfigLong(PSD(cl
), msg
->bus
, msg
->dev
, msg
->sub
, msg
->reg
, msg
->val
);
122 /* Class initialization and destruction */
123 static inline ULONG
GetPVR(void)
125 struct Library
*ProcessorBase
= OpenResource(PROCESSORNAME
);
129 struct TagItem tags
[] = {
130 { GCIT_Model
, (IPTR
)&pvr
},
139 static int PCI440_InitClass(LIBBASETYPEPTR LIBBASE
)
144 D(bug("PCI440: Driver initialization\n"));
147 if (pvr
== PVR_PPC460EX_B
) {
148 LIBBASE
->psd
.IntLine
= INTR_UIC0_PCI0_IN
;
149 LIBBASE
->psd
.CfgBase
= 0x00000000;
151 LIBBASE
->psd
.IntLine
= 0xff;
152 LIBBASE
->psd
.CfgBase
= 0x80000000;
155 struct pHidd_PCI_AddHardwareDriver msg
,*pmsg
=&msg
;
157 LIBBASE
->psd
.hiddPCIDriverAB
= OOP_ObtainAttrBase(IID_Hidd_PCIDriver
);
158 LIBBASE
->psd
.hiddAB
= OOP_ObtainAttrBase(IID_Hidd
);
159 if (LIBBASE
->psd
.hiddPCIDriverAB
== 0 || LIBBASE
->psd
.hiddAB
== 0)
161 D(bug("PCI440: ObtainAttrBases failed\n"));
165 msg
.driverClass
= LIBBASE
->psd
.driverClass
;
166 msg
.mID
= OOP_GetMethodID(IID_Hidd_PCI
, moHidd_PCI_AddHardwareDriver
);
167 D(bug("PCI440: Adding Driver to main the class OK\n"));
169 pci
= OOP_NewObject(NULL
, CLID_Hidd_PCI
, NULL
);
170 OOP_DoMethod(pci
, (OOP_Msg
)pmsg
);
171 OOP_DisposeObject(pci
);
173 D(bug("PCI440: CPU %p%p:%p%p PCI (0x%08x)\n",
174 inl_le(PCI0_POM0LAH
), inl_le(PCI0_POM0LAL
),
175 inl_le(PCI0_POM0PCIAH
), inl_le(PCI0_POM0PCIAL
),
176 ~(inl_le(PCI0_POM0SA
) & ~0xf) + 1
178 D(bug("PCI440: CPU %p%p:%p%p PCI (0x%08x)\n",
179 inl_le(PCI0_POM1LAH
), inl_le(PCI0_POM1LAL
),
180 inl_le(PCI0_POM1PCIAH
), inl_le(PCI0_POM1PCIAL
),
181 ~(inl_le(PCI0_POM1SA
) & ~0xf) + 1
183 uint64_t sa
= ((uint64_t)inl_le(PCI0_PIM0SAH
) << 32) | inl_le(PCI0_PIM0SAL
);
184 sa
= ~(sa
& ~0xfULL
) + 1;
185 D(bug("PCI440: PCI %p%p:%p%p CPU (0x%08x%08x)\n",
186 inl_le(PCI0_BAR0H
), inl_le(PCI0_BAR0L
) & ~0xf,
187 inl_le(PCI0_PIM0LAH
), inl_le(PCI0_PIM0LAL
),
188 (uint32_t)(sa
>>32), (uint32_t)sa
191 D(bug("PCI440: All OK\n"));
196 static int PCI440_ExpungeClass(LIBBASETYPEPTR LIBBASE
)
198 D(bug("PCI440: Class destruction\n"));
200 OOP_ReleaseAttrBase(IID_Hidd_PCIDriver
);
201 OOP_ReleaseAttrBase(IID_Hidd
);
206 ADD2INITLIB(PCI440_InitClass
, 0)
207 ADD2EXPUNGELIB(PCI440_ExpungeClass
, 0)