2 Copyright © 2008-2014, The AROS Development Team. All rights reserved.
6 #define __OOP_NOATTRBASES__
8 #include <exec/types.h>
12 #include <utility/tagitem.h>
14 #include <proto/exec.h>
15 #include <proto/utility.h>
16 #include <proto/oop.h>
17 #include <proto/openfirmware.h>
18 #include <proto/kernel.h>
20 #include <aros/symbolsets.h>
21 #include <asm/mpc5200b.h>
27 #include <aros/debug.h>
29 #undef HiddPCIDriverAttrBase
32 #define HiddPCIDriverAttrBase (PSD(cl)->hiddPCIDriverAB)
33 #define HiddAttrBase (PSD(cl)->hiddAB)
35 #define CFGADD(bus,dev,func,reg) \
36 ( 0x80000000 | ((bus)<<16) | \
37 ((dev)<<11) | ((func)<<8) | ((reg)&~3))
47 We overload the New method in order to introduce the Hidd Name and
48 HardwareName attributes.
50 OOP_Object
*PCIEfika__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
52 struct pRoot_New mymsg
;
54 struct TagItem mytags
[] = {
55 { aHidd_Name
, (IPTR
)"PCINative" },
56 { aHidd_HardwareName
, (IPTR
)"Efika5200 native direct access PCI driver" },
61 mymsg
.attrList
= (struct TagItem
*)&mytags
;
65 mytags
[2].ti_Tag
= TAG_MORE
;
66 mytags
[2].ti_Data
= (IPTR
)msg
->attrList
;
71 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
76 ULONG
ReadConfigLong(struct pci_staticdata
*psd
, UBYTE bus
, UBYTE dev
, UBYTE sub
, UBYTE reg
)
81 outl(CFGADD(bus
, dev
, sub
, reg
),(ULONG
*)(psd
->mbar
+ 0xdf8));
83 temp
=inl_le(psd
->pciio
);
84 outl(0, (ULONG
*)(psd
->mbar
+ 0xdf8));
91 ULONG
PCIEfika__Hidd_PCIDriver__ReadConfigLong(OOP_Class
*cl
, OOP_Object
*o
,
92 struct pHidd_PCIDriver_ReadConfigLong
*msg
)
94 ULONG val
= ReadConfigLong(PSD(cl
), msg
->bus
, msg
->dev
, msg
->sub
, msg
->reg
);
98 UWORD
ReadConfigWord(struct pci_staticdata
*psd
, UBYTE bus
, UBYTE dev
, UBYTE sub
, UBYTE reg
)
102 temp
.ul
= ReadConfigLong(psd
, bus
, dev
, sub
, reg
);
104 return temp
.uw
[1 - ((reg
&2)>>1)];
108 UWORD
PCIEfika__Hidd_PCIDriver__ReadConfigWord(OOP_Class
*cl
, OOP_Object
*o
,
109 struct pHidd_PCIDriver_ReadConfigWord
*msg
)
111 return ReadConfigWord(PSD(cl
), msg
->bus
, msg
->dev
, msg
->sub
, msg
->reg
);
114 UBYTE
PCIEfika__Hidd_PCIDriver__ReadConfigByte(OOP_Class
*cl
, OOP_Object
*o
,
115 struct pHidd_PCIDriver_ReadConfigByte
*msg
)
119 temp
.ul
= ReadConfigLong(PSD(cl
), msg
->bus
, msg
->dev
, msg
->sub
, msg
->reg
);
120 return temp
.ub
[3 - (msg
->reg
& 3)];
123 void WriteConfigLong(struct pci_staticdata
*psd
, UBYTE bus
, UBYTE dev
, UBYTE sub
, UBYTE reg
, ULONG val
)
126 outl(CFGADD(bus
, dev
, sub
, reg
),(ULONG
*)(psd
->mbar
+ 0xdf8));
128 outl_le(val
, psd
->pciio
);
129 outl(0, (ULONG
*)(psd
->mbar
+ 0xdf8));
134 void PCIEfika__Hidd_PCIDriver__WriteConfigLong(OOP_Class
*cl
, OOP_Object
*o
,
135 struct pHidd_PCIDriver_WriteConfigLong
*msg
)
137 WriteConfigLong(PSD(cl
), msg
->bus
, msg
->dev
, msg
->sub
, msg
->reg
, msg
->val
);
140 void PCIEfika__Hidd_PCIDriver__WriteConfigWord(OOP_Class
*cl
, OOP_Object
*o
,
141 struct pHidd_PCIDriver_WriteConfigWord
*msg
)
145 temp
.ul
= ReadConfigLong(PSD(cl
), msg
->bus
, msg
->dev
, msg
->sub
, msg
->reg
);
146 temp
.uw
[1 - ((msg
->reg
&2)>>1)] = msg
->val
;
147 WriteConfigLong(PSD(cl
), msg
->bus
, msg
->dev
, msg
->sub
, msg
->reg
, temp
.ul
);
150 void PCIEfika__Hidd_PCIDriver__WriteConfigByte(OOP_Class
*cl
, OOP_Object
*o
,
151 struct pHidd_PCIDriver_WriteConfigByte
*msg
)
155 temp
.ul
= ReadConfigLong(PSD(cl
), msg
->bus
, msg
->dev
, msg
->sub
, msg
->reg
);
156 temp
.ub
[3 - (msg
->reg
& 3)] = msg
->val
;
157 WriteConfigLong(PSD(cl
), msg
->bus
, msg
->dev
, msg
->sub
, msg
->reg
, temp
.ul
);
160 void *PCIEfika__Hidd_PCIDriver__MapPCI(OOP_Class
*cl
, OOP_Object
*o
,
161 struct pHidd_PCIDriver_MapPCI
*msg
)
163 void *KernelBase
= OpenResource("kernel.resource");
164 KrnMapGlobal(msg
->PCIAddress
, msg
->PCIAddress
, msg
->Length
, MAP_CacheInhibit
| MAP_Guarded
| MAP_Readable
| MAP_Writable
);
165 return msg
->PCIAddress
;
168 void *PCIEfika__Hidd_PCIDriver__AllocPCIMem(OOP_Class
*cl
, OOP_Object
*o
,
169 struct pHidd_PCIDriver_AllocPCIMem
*msg
)
171 void *KernelBase
= OpenResource("kernel.resource");
172 void *memory
= OOP_DoSuperMethod(cl
, o
, msg
);
176 KrnSetProtection(memory
, msg
->Size
, MAP_CacheInhibit
| MAP_Readable
| MAP_Writable
);
183 PCIDriver::FreePCIMemory(Address) frees previously allocated memory for PCI
186 VOID
PCIEfika__Hidd_PCIDriver__FreePCIMem(OOP_Class
*cl
, OOP_Object
*o
,
187 struct pHidd_PCIDriver_FreePCIMem
*msg
)
189 void *KernelBase
= OpenResource("kernel.resource");
190 KrnSetProtection(msg
->Address
, 4096, MAP_Readable
| MAP_Writable
);
191 OOP_DoSuperMethod(cl
, o
, msg
);
195 /* Class initialization and destruction */
197 static int PCIEfika_InitClass(LIBBASETYPEPTR LIBBASE
)
202 void *OpenFirmwareBase
= NULL
;
203 void *KernelBase
= NULL
;
205 D(bug("[PCI_Efika] Driver initialization\n"));
207 KernelBase
= OpenResource("kernel.resource");
208 OpenFirmwareBase
= OpenResource("openfirmware.resource");
209 D(bug("[PCI_Efika] OpenFirmwareBase = %08x\n", OpenFirmwareBase
));
211 void *key
= OF_OpenKey("/builtin");
214 void *prop
= OF_FindProperty(key
, "reg");
217 intptr_t *mbar
= OF_GetPropValue(prop
);
218 LIBBASE
->psd
.mbar
= (void *)(*mbar
);
220 D(bug("[PCI_Efika] MBAR located at %08x\n", LIBBASE
->psd
.mbar
));
224 D(bug("[PCI_Efika] PCITBATR0 = %08x\n", inl(LIBBASE
->psd
.mbar
+ 0x0d64)));
225 D(bug("[PCI_Efika] PCITBATR1 = %08x\n", inl(LIBBASE
->psd
.mbar
+ 0x0d68)));
227 D(bug("[PCI_Efika] PCIIW0BTAR = %08x\n", inl(LIBBASE
->psd
.mbar
+ 0x0d70)));
228 D(bug("[PCI_Efika] PCIIW1BTAR = %08x\n", inl(LIBBASE
->psd
.mbar
+ 0x0d74)));
229 D(bug("[PCI_Efika] PCIIW2BTAR = %08x\n", inl(LIBBASE
->psd
.mbar
+ 0x0d78)));
231 D(bug("[PCI_Efika] PCIIWCR = %08x\n", inl(LIBBASE
->psd
.mbar
+ 0x0d80)));
232 D(bug("[PCI_Efika] PCIICR = %08x\n", inl(LIBBASE
->psd
.mbar
+ 0x0d84)));
234 for (i
=0; i
< 3; i
++)
236 uint8_t attr
= inl(LIBBASE
->psd
.mbar
+ 0xd80) >> (24 - i
*8);
238 /* If bit 0 of attribute is cleared, then the window is not used */
242 temp
= inl(LIBBASE
->psd
.mbar
+ 0xd70 + i
*4);
243 uint32_t size
= 0x1000000 + ((temp
<< 8) & 0xff000000);
244 uint32_t base
= temp
& 0xff000000;
246 D(bug("[PCI_Efika] PCI %s: %08x - %08x\n", attr
& 8 ? "IO" : "MEM", base
, base
+ size
- 1));
249 LIBBASE
->psd
.pciio
= (uint8_t *)base
;
250 LIBBASE
->psd
.pciio_size
= size
;
254 LIBBASE
->psd
.pcimem
= (uint8_t *)base
;
255 LIBBASE
->psd
.pcimem_size
= size
;
259 /* Map first 64K of PCI IO space. More than that is not used anyway :) */
260 KrnMapGlobal(LIBBASE
->psd
.pciio
, LIBBASE
->psd
.pciio
, 0x10000, MAP_CacheInhibit
| MAP_Guarded
| MAP_Readable
| MAP_Writable
);
262 struct pHidd_PCI_AddHardwareDriver msg
,*pmsg
=&msg
;
264 LIBBASE
->psd
.hiddPCIDriverAB
= OOP_ObtainAttrBase(IID_Hidd_PCIDriver
);
265 LIBBASE
->psd
.hiddAB
= OOP_ObtainAttrBase(IID_Hidd
);
266 if (LIBBASE
->psd
.hiddPCIDriverAB
== 0 || LIBBASE
->psd
.hiddAB
== 0)
268 D(bug("[PCI_Efika] ObtainAttrBases failed\n"));
272 msg
.driverClass
= LIBBASE
->psd
.driverClass
;
273 msg
.mID
= OOP_GetMethodID(IID_Hidd_PCI
, moHidd_PCI_AddHardwareDriver
);
274 D(bug("[PCI_Efika] Adding Driver to main the class OK\n"));
276 pci
= OOP_NewObject(NULL
, CLID_Hidd_PCI
, NULL
);
277 OOP_DoMethod(pci
, (OOP_Msg
)pmsg
);
278 OOP_DisposeObject(pci
);
280 D(bug("[PCI_Efika] All OK\n"));
285 static int PCIEfika_ExpungeClass(LIBBASETYPEPTR LIBBASE
)
287 D(bug("[PCI_Efika] Class destruction\n"));
289 OOP_ReleaseAttrBase(IID_Hidd_PCIDriver
);
290 OOP_ReleaseAttrBase(IID_Hidd
);
295 ADD2INITLIB(PCIEfika_InitClass
, 0)
296 ADD2EXPUNGELIB(PCIEfika_ExpungeClass
, 0)