Fixed compatibility of output.
[AROS.git] / arch / ppc-chrp / efika / pci / driverclass.c
blob32ff0a22fe354045a539b377ea2cb95d1efdfcbe
1 /*
2 Copyright © 2008-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define __OOP_NOATTRBASES__
8 #include <exec/types.h>
9 #include <hidd/pci.h>
10 #include <oop/oop.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>
22 #include <asm/io.h>
24 #include "pci.h"
26 #define DEBUG 1
27 #include <aros/debug.h>
29 #undef HiddPCIDriverAttrBase
30 #undef HiddAttrBase
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))
39 typedef union _pcicfg
41 ULONG ul;
42 UWORD uw[2];
43 UBYTE ub[4];
44 } pcicfg;
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" },
57 { TAG_DONE, 0 }
60 mymsg.mID = msg->mID;
61 mymsg.attrList = (struct TagItem *)&mytags;
63 if (msg->attrList)
65 mytags[2].ti_Tag = TAG_MORE;
66 mytags[2].ti_Data = (IPTR)msg->attrList;
69 msg = &mymsg;
71 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
73 return o;
76 ULONG ReadConfigLong(struct pci_staticdata *psd, UBYTE bus, UBYTE dev, UBYTE sub, UBYTE reg)
78 ULONG temp;
80 Disable();
81 outl(CFGADD(bus, dev, sub, reg),(ULONG*)(psd->mbar + 0xdf8));
82 sync();
83 temp=inl_le(psd->pciio);
84 outl(0, (ULONG *)(psd->mbar + 0xdf8));
85 sync();
86 Enable();
88 return temp;
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);
95 return val;
98 UWORD ReadConfigWord(struct pci_staticdata *psd, UBYTE bus, UBYTE dev, UBYTE sub, UBYTE reg)
100 pcicfg temp;
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)
117 pcicfg temp;
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)
125 Disable();
126 outl(CFGADD(bus, dev, sub, reg),(ULONG*)(psd->mbar + 0xdf8));
127 sync();
128 outl_le(val, psd->pciio);
129 outl(0, (ULONG *)(psd->mbar + 0xdf8));
130 sync();
131 Enable();
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)
143 pcicfg temp;
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)
153 pcicfg temp;
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);
174 if (memory)
176 KrnSetProtection(memory, msg->Size, MAP_CacheInhibit | MAP_Readable | MAP_Writable);
179 return memory;
183 PCIDriver::FreePCIMemory(Address) frees previously allocated memory for PCI
184 devices
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)
199 OOP_Object *pci;
200 int i;
201 ULONG temp;
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");
212 if (key)
214 void *prop = OF_FindProperty(key, "reg");
215 if (prop)
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 */
239 if ((attr & 1) == 0)
240 continue;
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));
247 if (attr & 8)
249 LIBBASE->psd.pciio = (uint8_t *)base;
250 LIBBASE->psd.pciio_size = size;
252 else
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"));
269 return FALSE;
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"));
282 return TRUE;
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);
292 return TRUE;
295 ADD2INITLIB(PCIEfika_InitClass, 0)
296 ADD2EXPUNGELIB(PCIEfika_ExpungeClass, 0)