Hint added.
[AROS.git] / workbench / hidds / nouveau / pci-device-mock / pcimockhardwareclass.c
bloba04f3c586a0610922479ddc66eddb84b99990ebc
1 /*
2 Copyright 2011, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <aros/debug.h>
7 #include <proto/oop.h>
9 #include "pci.h" /* From hidd.pci */
11 #include "pcimockhardware.h"
12 #include "pcimockhardware_intern.h"
13 #include "pcimock_intern.h"
15 #undef HiddPCIMockHardwareAttrBase
16 #define HiddPCIMockHardwareAttrBase (SD(cl)->hiddPCIMockHardwareAB)
18 OOP_Object * METHOD(PCIMockHardware, Root, New)
20 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
21 struct HIDDPCIMockHardwareData * hwdata = OOP_INST_DATA(cl, o);
22 ULONG i;
24 for (i = 0; i < PCI_REGIONS_COUNT; i++)
25 ALLOC_ASR_NULL(hwdata, i);
27 return o;
30 VOID PCIMockHardware__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
32 struct HIDDPCIMockHardwareData * hwdata = OOP_INST_DATA(cl, o);
33 ULONG i;
35 for (i = 0; i < PCI_REGIONS_COUNT; i++)
36 if (hwdata->Regions[i].Address != (IPTR)0) FreeVec((APTR)hwdata->Regions[i].Address);
39 VOID METHOD(PCIMockHardware, Root, Get)
41 struct HIDDPCIMockHardwareData * hwdata = OOP_INST_DATA(cl, o);
42 ULONG idx;
44 if (IS_PCIMOCKHARDWARE_ATTR(msg->attrID, idx))
46 switch (idx)
48 case aoHidd_PCIMockHardware_ConfigSpaceAddr:
49 *msg->storage = hwdata->Regions[PCI_CONFIG_SPACE].Address;
50 return;
54 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
57 #define SUPPORT_BAR_SIZE_QUERY(hwdata, offset, n) \
58 if (GET_ASR_DWORD(hwdata, PCI_CONFIG_SPACE, offset) == 0xffffffff) \
59 { \
60 ULONG tmp = hwdata->Regions[n].Size; tmp -= 1; tmp = ~tmp; \
61 SET_ASR_DWORD(hwdata, PCI_CONFIG_SPACE, offset, tmp); \
62 } \
65 VOID METHOD(PCIMockHardware, Hidd_PCIMockHardware, MemoryChangedAtAddress)
67 struct HIDDPCIMockHardwareData * hwdata = OOP_INST_DATA(cl, o);
69 /* Detect in which address space the address is located and get relative offset */
70 struct RegionAndOffset rao = HIDDPCIMockHardwareDetectRegionAndOffset(hwdata, msg->memoryaddress);
72 if (rao.Region == -1)
73 return;
75 /* Perform action based on type of address space and offset/register */
76 if (rao.Region == PCI_CONFIG_SPACE)
78 switch(rao.Offset)
80 case(PCICS_BAR0) :
81 SUPPORT_BAR_SIZE_QUERY(hwdata, PCICS_BAR0, PCI_BAR0);
82 break;
83 case(PCICS_BAR1) :
84 SUPPORT_BAR_SIZE_QUERY(hwdata, PCICS_BAR1, PCI_BAR1);
85 break;
86 case(PCICS_BAR2) :
87 SUPPORT_BAR_SIZE_QUERY(hwdata, PCICS_BAR2, PCI_BAR2);
88 break;
89 case(PCICS_BAR3) :
90 SUPPORT_BAR_SIZE_QUERY(hwdata, PCICS_BAR3, PCI_BAR3);
91 break;
92 case(PCICS_BAR4) :
93 SUPPORT_BAR_SIZE_QUERY(hwdata, PCICS_BAR4, PCI_BAR4);
94 break;
95 case(PCICS_BAR5) :
96 SUPPORT_BAR_SIZE_QUERY(hwdata, PCICS_BAR5, PCI_BAR5);
97 break;
98 case(PCICS_EXPROM_BASE) :
99 SUPPORT_BAR_SIZE_QUERY(hwdata, PCICS_EXPROM_BASE, PCI_ROM);
100 break;
101 default :
102 bug("[PCIMockHardware(0x%x:0x%x)->MemoryChangedAtAddress - %d:0x%x Unhandled\n",
103 (GET_ASR_DWORD(hwdata, PCI_CONFIG_SPACE, 0x00) & 0xffff),
104 ((GET_ASR_DWORD(hwdata, PCI_CONFIG_SPACE, 0x00) >> 16) & 0xffff),
105 rao.Region, rao.Offset);
106 break;
111 VOID METHOD(PCIMockHardware, Hidd_PCIMockHardware, MemoryReadAtAddress)
113 struct HIDDPCIMockHardwareData * hwdata = OOP_INST_DATA(cl, o);
115 /* Detect in which address space the address is located and get relative offset */
116 struct RegionAndOffset rao = HIDDPCIMockHardwareDetectRegionAndOffset(hwdata, msg->memoryaddress);
118 if (rao.Region == -1)
119 return;
121 bug("[PCIMockHardware(0x%x:0x%x)->MemoryReadAtAddress - %d:0x%x Unhandled\n",
122 (GET_ASR_DWORD(hwdata, PCI_CONFIG_SPACE, 0x00) & 0xffff),
123 ((GET_ASR_DWORD(hwdata, PCI_CONFIG_SPACE, 0x00) >> 16) & 0xffff),
124 rao.Region, rao.Offset);
127 struct RegionAndOffset HIDDPCIMockHardwareDetectRegionAndOffset(struct HIDDPCIMockHardwareData * hwdata, IPTR address)
129 ULONG i = 0;
130 struct RegionAndOffset rao = {-1, ~0};
132 for (i = 0; i < PCI_REGIONS_COUNT; i++)
133 if ((hwdata->Regions[i].Address <= address) && ((hwdata->Regions[i].Address + hwdata->Regions[i].Size) >= address))
135 rao.Region = i;
136 rao.Offset = address - hwdata->Regions[i].Address;
137 break;
140 return rao;