Fix IO memory access .. SB128 driver makes noises in VMWare - CMI is untested (Curren...
[AROS.git] / workbench / devs / AHI / Drivers / SB128 / pci_aros.c
blobc63048de88793cf861678a4c31ada28a06e3e637
1 #define __OOP_NOATTRBASES__
3 #include <utility/hooks.h>
4 #include <exec/interrupts.h>
5 #include <aros/macros.h>
6 #include <aros/io.h>
7 #include <oop/oop.h>
8 #include <hidd/pci.h>
9 #include <hidd/irq.h>
10 #include <aros/asmcall.h>
12 #include <proto/oop.h>
14 #include "DriverData.h"
15 #include "pci_wrapper.h"
17 #include <aros/debug.h>
18 #define KPrintF kprintf
20 struct Library *OOPBase;
22 static OOP_AttrBase __IHidd_PCIDev;
23 static OOP_Object *pciobj, *irqobj;
25 static OOP_MethodID mid_RB;
26 static OOP_MethodID mid_RW;
27 static OOP_MethodID mid_RL;
29 static OOP_MethodID mid_WB;
30 static OOP_MethodID mid_WW;
31 static OOP_MethodID mid_WL;
33 static HIDDT_IRQ_Handler inthandler;
34 static BOOL inthandler_added;
36 BOOL ahi_pci_init(struct DriverBase* AHIsubBase)
38 OOPBase = OpenLibrary(AROSOOP_NAME, 0);
39 if (OOPBase)
41 __IHidd_PCIDev = OOP_ObtainAttrBase(IID_Hidd_PCIDevice);
42 if (__IHidd_PCIDev)
44 pciobj = OOP_NewObject(NULL, CLID_Hidd_PCI, NULL);
45 irqobj = OOP_NewObject(NULL, CLID_Hidd_IRQ, NULL);
47 if (pciobj && irqobj)
49 mid_RB = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
50 mid_RW = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigWord);
51 mid_RL = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigLong);
53 mid_WB = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
54 mid_WW = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigWord);
55 mid_WL = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigLong);
57 return TRUE;
62 return FALSE;
65 void ahi_pci_exit(void)
67 if (irqobj)
68 OOP_DisposeObject(irqobj);
69 if (pciobj)
70 OOP_DisposeObject(pciobj);
71 if (__IHidd_PCIDev)
72 OOP_ReleaseAttrBase(IID_Hidd_PCIDevice);
73 if (OOPBase)
74 CloseLibrary(OOPBase);
77 struct enum_data
79 OOP_Object *prev_dev;
80 OOP_Object *found_dev;
83 static AROS_UFH3(void, Enumerator,
84 AROS_UFHA(struct Hook *, hook, A0),
85 AROS_UFHA(OOP_Object *, device, A2),
86 AROS_UFHA(APTR, msg, A1))
88 AROS_USERFUNC_INIT
90 struct enum_data *ed = (struct enum_data *)hook->h_Data;
92 if ((ed->found_dev == 0) && (device != ed->prev_dev))
94 ed->found_dev = device;
97 AROS_USERFUNC_EXIT
101 APTR ahi_pci_find_device(ULONG vendorid, ULONG deviceid, APTR dev)
103 struct enum_data ed;
105 struct Hook FindHook =
107 h_Entry: (HOOKFUNC)Enumerator,
108 h_Data: &ed,
111 struct TagItem Reqs[] =
113 #if 0
114 { tHidd_PCI_Class , 0x04 }, /* Multimedia */
115 { tHidd_PCI_SubClass , 0x01 }, /* Audio */
116 #endif
117 { tHidd_PCI_VendorID , vendorid },
118 { tHidd_PCI_ProductID , deviceid },
119 { TAG_DONE , 0 },
122 struct pHidd_PCI_EnumDevices enummsg =
124 mID: OOP_GetMethodID(CLID_Hidd_PCI, moHidd_PCI_EnumDevices),
125 callback: &FindHook,
126 requirements: (struct TagItem *)&Reqs,
127 }, *msg = &enummsg;
129 ed.prev_dev = (OOP_Object *)dev;
130 ed.found_dev = 0;
132 OOP_DoMethod(pciobj, (OOP_Msg)msg);
134 //KPrintF("ahi_pci_find_device: found_dev = %lx\n", ed.found_dev);
136 return (APTR)ed.found_dev;
139 ULONG pci_inl(ULONG addr, struct SB128_DATA *card)
141 return LONGIN(card->iobase + addr);
144 UWORD pci_inw(ULONG addr, struct SB128_DATA *card)
146 return WORDIN(card->iobase + addr);
149 UBYTE pci_inb(ULONG addr, struct SB128_DATA *card)
151 return BYTEIN(card->iobase + addr);
154 void pci_outl(ULONG value, ULONG addr, struct SB128_DATA *card)
156 LONGOUT(card->iobase + addr, value);
159 void pci_outw(UWORD value, ULONG addr, struct SB128_DATA *card)
161 WORDOUT(card->iobase + addr, value);
164 void pci_outb(UBYTE value, ULONG addr, struct SB128_DATA *card)
166 BYTEOUT(card->iobase + addr, value);
169 void outb_setbits(UBYTE value, ULONG addr, struct SB128_DATA *card)
171 UBYTE data = pci_inb(addr, card);
172 data |= value;
174 pci_outb(data, addr, card);
178 void outb_clearbits(UBYTE value, ULONG addr, struct SB128_DATA *card)
180 UBYTE data = pci_inb(addr, card);
181 data &= ~value;
183 pci_outb(data, addr, card);
187 void outw_setbits(UWORD value, ULONG addr, struct SB128_DATA *card)
189 UWORD data = pci_inw(addr, card);
190 data |= value;
192 pci_outw(data, addr, card);
196 void outw_clearbits(UWORD value, ULONG addr, struct SB128_DATA *card)
198 UWORD data = pci_inw(addr, card);
199 data &= ~value;
201 pci_outw(data, addr, card);
205 void outl_setbits(ULONG value, ULONG addr, struct SB128_DATA *card)
207 ULONG data = pci_inl(addr, card);
208 data |= value;
210 pci_outl(data, addr, card);
214 void outl_clearbits(ULONG value, ULONG addr, struct SB128_DATA *card)
216 ULONG data = pci_inl(addr, card);
217 data &= ~value;
219 pci_outl(data, addr, card);
223 ULONG inl_config(UBYTE reg, APTR dev)
225 struct pHidd_PCIDevice_ReadConfigLong msg;
227 msg.mID = mid_RL;
228 msg.reg = reg;
230 return OOP_DoMethod((OOP_Object *)dev, (OOP_Msg)&msg);
233 UWORD inw_config(UBYTE reg, APTR dev)
235 struct pHidd_PCIDevice_ReadConfigWord msg;
237 msg.mID = mid_RW;
238 msg.reg = reg;
240 return OOP_DoMethod((OOP_Object *)dev, (OOP_Msg)&msg);
243 UBYTE inb_config(UBYTE reg, APTR dev)
245 struct pHidd_PCIDevice_ReadConfigByte msg;
247 msg.mID = mid_RB;
248 msg.reg = reg;
250 return OOP_DoMethod(dev, (OOP_Msg)&msg);
253 void outl_config(UBYTE reg, ULONG val, APTR dev)
255 struct pHidd_PCIDevice_WriteConfigLong msg;
257 msg.mID = mid_WL;
258 msg.reg = reg;
259 msg.val = val;
261 OOP_DoMethod((OOP_Object *)dev, (OOP_Msg)&msg);
264 void outw_config(UBYTE reg, UWORD val, APTR dev)
266 struct pHidd_PCIDevice_WriteConfigWord msg;
268 msg.mID = mid_WW;
269 msg.reg = reg;
270 msg.val = val;
272 OOP_DoMethod((OOP_Object *)dev, (OOP_Msg)&msg);
275 void outb_config(UBYTE reg, UBYTE val, APTR dev)
277 struct pHidd_PCIDevice_WriteConfigByte msg;
279 msg.mID = mid_WB;
280 msg.reg = reg;
281 msg.val = val;
283 OOP_DoMethod((OOP_Object *)dev, (OOP_Msg)&msg);
286 ULONG ahi_pci_get_irq(APTR dev)
288 IPTR val;
290 OOP_GetAttr((OOP_Object *)dev, aHidd_PCIDevice_INTLine, &val);
292 return (ULONG)val;
295 static void interrupt_code(HIDDT_IRQ_Handler *irq, HIDDT_IRQ_HwInfo *hw)
297 struct Interrupt *i = (struct Interrupt *)irq->h_Data;
299 AROS_UFC3(void, i->is_Code,
300 AROS_UFCA(APTR, i->is_Data, A1),
301 AROS_UFCA(APTR, i->is_Code, A5),
302 AROS_UFCA(struct ExecBase *, SysBase, A6));
306 BOOL ahi_pci_add_intserver(struct Interrupt *i, APTR dev)
308 struct pHidd_IRQ_AddHandler __msg__, *msg = &__msg__;
309 IPTR val;
311 OOP_GetAttr((OOP_Object *)dev, aHidd_PCIDevice_INTLine, &val);
313 inthandler.h_Node.ln_Pri = 1;
314 inthandler.h_Node.ln_Name = "SB128 IRQ";
315 inthandler.h_Code = interrupt_code;
316 inthandler.h_Data = i;
318 msg->mID = OOP_GetMethodID(CLID_Hidd_IRQ, moHidd_IRQ_AddHandler);
319 msg->handlerinfo = &inthandler;
320 msg->id = val;
322 OOP_DoMethod(irqobj, (OOP_Msg)msg);
324 inthandler_added = TRUE;
326 return TRUE;
329 void ahi_pci_rem_intserver(struct Interrupt *i, APTR dev)
331 if (inthandler_added)
333 struct pHidd_IRQ_RemHandler __msg__ =
335 mID: OOP_GetMethodID(CLID_Hidd_IRQ, moHidd_IRQ_RemHandler),
336 handlerinfo: &inthandler,
337 }, *msg = &__msg__;
339 OOP_DoMethod(irqobj, (OOP_Msg)msg);
341 inthandler_added = FALSE;
344 KPrintF("ahi_pci_rem_intserver\n");
348 APTR ahi_pci_get_base_address(WORD which, APTR dev)
350 OOP_AttrID attr = 0;
351 IPTR val = 0;
353 switch(which)
355 case 0:
356 attr = aHidd_PCIDevice_Base0;
357 break;
359 case 1:
360 attr = aHidd_PCIDevice_Base1;
361 break;
363 case 2:
364 attr = aHidd_PCIDevice_Base2;
365 break;
367 case 3:
368 attr = aHidd_PCIDevice_Base3;
369 break;
371 case 4:
372 attr = aHidd_PCIDevice_Base4;
373 break;
375 case 5:
376 attr = aHidd_PCIDevice_Base5;
377 break;
379 default:
380 return 0;
383 OOP_GetAttr((OOP_Object *)dev, attr, &val);
385 //KPrintF("ahi_pci_get_base_address. Result %lx\n", val);
387 return (APTR)val;
390 ULONG ahi_pci_get_base_size(WORD which, APTR dev)
392 OOP_AttrID attr = 0;
393 IPTR val = 0;
395 switch(which)
397 case 0:
398 attr = aHidd_PCIDevice_Size0;
399 break;
401 case 1:
402 attr = aHidd_PCIDevice_Size1;
403 break;
405 case 2:
406 attr = aHidd_PCIDevice_Size2;
407 break;
409 case 3:
410 attr = aHidd_PCIDevice_Size3;
411 break;
413 case 4:
414 attr = aHidd_PCIDevice_Size4;
415 break;
417 case 5:
418 attr = aHidd_PCIDevice_Size5;
419 break;
421 default:
422 return 0;
425 OOP_GetAttr((OOP_Object *)dev, attr, &val);
427 //KPrintF("ahi_pci_get_base_size. Result %lx\n", val);
429 return (ULONG)val;
435 ULONG ahi_pci_get_type(WORD which, APTR dev)
437 OOP_AttrID attr = 0;
438 IPTR val = 0;
440 switch(which)
442 case 0:
443 attr = aHidd_PCIDevice_Type0;
444 break;
446 case 1:
447 attr = aHidd_PCIDevice_Type1;
448 break;
450 case 2:
451 attr = aHidd_PCIDevice_Type2;
452 break;
454 case 3:
455 attr = aHidd_PCIDevice_Type3;
456 break;
458 case 4:
459 attr = aHidd_PCIDevice_Type4;
460 break;
462 case 5:
463 attr = aHidd_PCIDevice_Type5;
464 break;
466 default:
467 return 0;
470 OOP_GetAttr((OOP_Object *)dev, attr, &val);
472 //KPrintF("ahi_pci_get_type. Result %lx\n", val);
474 return (ULONG) val;