2 Copyright 2011, The AROS Development Team. All rights reserved.
6 #include <aros/debug.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
);
24 for (i
= 0; i
< PCI_REGIONS_COUNT
; i
++)
25 ALLOC_ASR_NULL(hwdata
, i
);
30 VOID
PCIMockHardware__Root__Dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
32 struct HIDDPCIMockHardwareData
* hwdata
= OOP_INST_DATA(cl
, o
);
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
);
44 if (IS_PCIMOCKHARDWARE_ATTR(msg
->attrID
, idx
))
48 case aoHidd_PCIMockHardware_ConfigSpaceAddr
:
49 *msg
->storage
= hwdata
->Regions
[PCI_CONFIG_SPACE
].Address
;
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) \
60 ULONG tmp = hwdata->Regions[n].Size; tmp -= 1; tmp = ~tmp; \
61 SET_ASR_DWORD(hwdata, PCI_CONFIG_SPACE, offset, tmp); \
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
);
75 /* Perform action based on type of address space and offset/register */
76 if (rao
.Region
== PCI_CONFIG_SPACE
)
81 SUPPORT_BAR_SIZE_QUERY(hwdata
, PCICS_BAR0
, PCI_BAR0
);
84 SUPPORT_BAR_SIZE_QUERY(hwdata
, PCICS_BAR1
, PCI_BAR1
);
87 SUPPORT_BAR_SIZE_QUERY(hwdata
, PCICS_BAR2
, PCI_BAR2
);
90 SUPPORT_BAR_SIZE_QUERY(hwdata
, PCICS_BAR3
, PCI_BAR3
);
93 SUPPORT_BAR_SIZE_QUERY(hwdata
, PCICS_BAR4
, PCI_BAR4
);
96 SUPPORT_BAR_SIZE_QUERY(hwdata
, PCICS_BAR5
, PCI_BAR5
);
98 case(PCICS_EXPROM_BASE
) :
99 SUPPORT_BAR_SIZE_QUERY(hwdata
, PCICS_EXPROM_BASE
, PCI_ROM
);
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
);
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)
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
)
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
))
136 rao
.Offset
= address
- hwdata
->Regions
[i
].Address
;