2 Copyright © 2005-2013, The AROS Development Team. All rights reserved.
7 #include <exec/types.h>
8 #include <utility/tagitem.h>
9 #include <libraries/prometheus.h>
11 #include <proto/exec.h>
12 #include <proto/kernel.h>
13 #include <proto/utility.h>
14 #include <proto/oop.h>
16 #include "prometheus_intern.h"
18 #define KernelBase (base->kernelBase)
20 /* Private prototypes */
22 static const struct TagItem map_tag_list
[] =
24 {PRM_Vendor
, aoHidd_PCIDevice_VendorID
},
25 {PRM_Device
, aoHidd_PCIDevice_ProductID
},
26 {PRM_Revision
, aoHidd_PCIDevice_RevisionID
},
27 {PRM_Class
, aoHidd_PCIDevice_Class
},
28 {PRM_SubClass
, aoHidd_PCIDevice_SubClass
},
29 {PRM_MemoryAddr0
, aoHidd_PCIDevice_Base0
},
30 {PRM_MemoryAddr1
, aoHidd_PCIDevice_Base1
},
31 {PRM_MemoryAddr2
, aoHidd_PCIDevice_Base2
},
32 {PRM_MemoryAddr3
, aoHidd_PCIDevice_Base3
},
33 {PRM_MemoryAddr4
, aoHidd_PCIDevice_Base4
},
34 {PRM_MemoryAddr5
, aoHidd_PCIDevice_Base5
},
35 {PRM_ROM_Address
, aoHidd_PCIDevice_RomBase
},
36 {PRM_MemorySize0
, aoHidd_PCIDevice_Size0
},
37 {PRM_MemorySize1
, aoHidd_PCIDevice_Size1
},
38 {PRM_MemorySize2
, aoHidd_PCIDevice_Size2
},
39 {PRM_MemorySize3
, aoHidd_PCIDevice_Size3
},
40 {PRM_MemorySize4
, aoHidd_PCIDevice_Size4
},
41 {PRM_MemorySize5
, aoHidd_PCIDevice_Size5
},
42 {PRM_ROM_Size
, aoHidd_PCIDevice_RomSize
},
43 {PRM_SlotNumber
, aoHidd_PCIDevice_Dev
},
44 {PRM_FunctionNumber
, aoHidd_PCIDevice_Sub
},
48 static const struct Node foreign_owner
=
53 static UPINT
GetOwner(struct LibBase
*base
, PCIBoard
*board
)
55 const struct Node
*owner
= board
->owner
;
60 * The board is not owned via prometheus.library API.
61 * But it could be owned via some other API. In this case
62 * we supply own struct Node.
66 OOP_GetAttr(board
->aros_board
, aHidd_PCIDevice_Owner
, &aros_owner
);
68 owner
= &foreign_owner
;
74 /***************************************************************************
77 AROS_LH2(PCIBoard
*, Prm_FindBoardTagList
,
80 AROS_LHA(PCIBoard
*, previous
, A0
),
81 AROS_LHA(struct TagItem
*, tag_list
, A1
),
84 struct Library
*, PrometheusBase
, 5, Prometheus
)
87 Find the board whose properties match the given set
91 previous - an opaque pointer to previously found board,
92 or NULL to start the search from the beginning
93 tag_list - a pointer to a taglist specifying attributes to
94 match against. If NULL, then all boards will be
98 A pointer to next matching board object or NULL if the search
99 has ended and there is no more match.
102 You can search for boards with some specific owner using
103 PRM_BoardOwner tag. However note that in AROS prometheus.library
104 is a wrapper on top of native object-oriented framework. This
105 framework uses different concept of device ownership, and
106 prometheus.library cannot determine correct owner value for devices
107 locked using those APIs. Those devices are treated as having the
108 same owner named "AROS", however in reality their owners will be
111 ***************************************************************************/
115 struct LibBase
*base
= (APTR
)PrometheusBase
;
117 struct TagItem
*temp_tag_list
;
118 struct TagItem
*tag_item
;
119 struct PCIBoard
*board
, *tail
;
120 BOOL success
= FALSE
;
124 board
= (APTR
)previous
->node
.mln_Succ
;
126 board
= (APTR
)base
->boards
.mlh_Head
;
127 tail
= (APTR
)&base
->boards
.mlh_Tail
;
129 while(board
!= tail
&& !success
)
131 /* Check if the current board matches all requirements */
133 temp_tag_list
= tag_list
;
135 while((tag_item
= NextTagItem(&temp_tag_list
)) != NULL
)
137 tag
= tag_item
->ti_Tag
;
142 board_data
= GetOwner(base
, board
);
146 aros_tag
= GetTagData(tag
, TAG_DONE
, (struct TagItem
*)map_tag_list
);
147 if (aros_tag
!= TAG_DONE
)
148 OOP_GetAttr(board
->aros_board
, base
->pcidevice_attr_base
+ aros_tag
,
155 if(board_data
!= tag_item
->ti_Data
)
160 board
= (APTR
)board
->node
.mln_Succ
;
171 /***************************************************************************
174 AROS_LH2(ULONG
, Prm_GetBoardAttrsTagList
,
177 AROS_LHA(PCIBoard
*, board
, A0
),
178 AROS_LHA(struct TagItem
*, tag_list
, A1
),
181 struct Library
*, PrometheusBase
, 6, Prometheus
)
184 Returns information about the board according to the
188 board - an opaque pointer to board object to query
189 tag_list - a list of attributes to query. ti_Data for
190 every tag should be a pointer to IPTR storage
191 where the data will be written. For unrecognized
192 tags a value of 0 will be returned. Tags with
193 ti_Data set to NULL will be skipped.
196 Number of succesfully processed tags.
199 AROS implementation of prometheus.library is a wrapper on top of
200 object-oriented driver stack. Software can use either
201 prometheus.library, or some other wrapper API (like openpci.library)
202 or HIDD object-oriented API directly. Concept of device ownership
203 is different across different APIs, so this method returns correct
204 device owner only if the device was locked using prometheus.library's
205 Prm_SetBoardAttrsTagList() function. If device's owner uses another
206 API, prometheus.library will specify "AROS" default name.
208 ***************************************************************************/
212 struct LibBase
*base
= (APTR
)PrometheusBase
;
216 struct TagItem
*tag_item
;
218 while((tag_item
= NextTagItem(&tag_list
)) != NULL
)
220 if (!tag_item
->ti_Data
)
223 if(tag_item
->ti_Tag
== PRM_BoardOwner
)
225 tag_data_ptr
= (UPINT
*)tag_item
->ti_Data
;
226 *tag_data_ptr
= GetOwner(base
, board
);
231 aros_tag
= GetTagData(tag_item
->ti_Tag
, TAG_DONE
, (struct TagItem
*)map_tag_list
);
232 if(aros_tag
!= TAG_DONE
)
234 OOP_GetAttr(board
->aros_board
,
235 base
->pcidevice_attr_base
+ aros_tag
,
236 (IPTR
*)tag_item
->ti_Data
);
249 /***************************************************************************
252 AROS_LH2(ULONG
, Prm_SetBoardAttrsTagList
,
255 AROS_LHA(PCIBoard
*, board
, A0
),
256 AROS_LHA(struct TagItem
*, tag_list
, A1
),
259 struct Library
*, PrometheusBase
, 13, Prometheus
)
267 ***************************************************************************/
271 struct LibBase
*base
= (struct LibBase
*)PrometheusBase
;
273 struct Node
*new_owner
;
274 struct TagItem
*tag_item
;
276 tag_item
= FindTagItem(PRM_BoardOwner
, tag_list
);
279 new_owner
= (APTR
)tag_item
->ti_Data
;
283 CONST_STRPTR new_str
= new_owner
->ln_Name
;
284 CONST_STRPTR old_str
;
286 /* Just in case. We cannot specify NULL owner to PCIDevice::Obtain() */
288 new_str
= base
->lib_header
.lib_Node
.ln_Name
;
290 old_str
= HIDD_PCIDevice_Obtain(board
->aros_board
, new_str
);
293 board
->owner
= new_owner
;
297 else if (board
->owner
)
299 HIDD_PCIDevice_Release(board
->aros_board
);
312 /***************************************************************************
315 AROS_LH2(UBYTE
, Prm_ReadConfigByte
,
318 AROS_LHA(PCIBoard
*, board
, A0
),
319 AROS_LHA(UBYTE
, offset
, D0
),
322 struct Library
*, PrometheusBase
, 9, Prometheus
)
330 ***************************************************************************/
334 struct LibBase
*base
= (struct LibBase
*)PrometheusBase
;
336 return HIDD_PCIDevice_ReadConfigByte(board
->aros_board
, offset
);
343 /***************************************************************************
346 AROS_LH3(VOID
, Prm_WriteConfigByte
,
349 AROS_LHA(PCIBoard
*, board
, A0
),
350 AROS_LHA(UBYTE
, data
, D0
),
351 AROS_LHA(UBYTE
, offset
, D1
),
354 struct Library
*, PrometheusBase
, 12, Prometheus
)
362 ***************************************************************************/
366 struct LibBase
*base
= (struct LibBase
*)PrometheusBase
;
368 HIDD_PCIDevice_WriteConfigByte(board
->aros_board
, offset
, data
);
375 /***************************************************************************
378 AROS_LH2(UWORD
, Prm_ReadConfigWord
,
381 AROS_LHA(PCIBoard
*, board
, A0
),
382 AROS_LHA(UBYTE
, offset
, D0
),
385 struct Library
*, PrometheusBase
, 8, Prometheus
)
393 ***************************************************************************/
397 struct LibBase
*base
= (struct LibBase
*)PrometheusBase
;
399 return HIDD_PCIDevice_ReadConfigWord(board
->aros_board
, offset
& ~0x1);
406 /***************************************************************************
409 AROS_LH3(VOID
, Prm_WriteConfigWord
,
412 AROS_LHA(PCIBoard
*, board
, A0
),
413 AROS_LHA(UWORD
, data
, D0
),
414 AROS_LHA(UBYTE
, offset
, D1
),
417 struct Library
*, PrometheusBase
, 11, Prometheus
)
425 ***************************************************************************/
429 struct LibBase
*base
= (struct LibBase
*)PrometheusBase
;
431 HIDD_PCIDevice_WriteConfigWord(board
->aros_board
, offset
& ~0x1, data
);
438 /***************************************************************************
441 AROS_LH2(ULONG
, Prm_ReadConfigLong
,
444 AROS_LHA(PCIBoard
*, board
, A0
),
445 AROS_LHA(UBYTE
, offset
, D0
),
448 struct Library
*, PrometheusBase
, 7, Prometheus
)
456 ***************************************************************************/
460 struct LibBase
*base
= (struct LibBase
*)PrometheusBase
;
462 return HIDD_PCIDevice_ReadConfigLong(board
->aros_board
, offset
& ~0x3);
469 /***************************************************************************
472 AROS_LH3(VOID
, Prm_WriteConfigLong
,
475 AROS_LHA(PCIBoard
*, board
, A0
),
476 AROS_LHA(ULONG
, data
, D0
),
477 AROS_LHA(UBYTE
, offset
, D1
),
480 struct Library
*, PrometheusBase
, 10, Prometheus
)
488 ***************************************************************************/
492 struct LibBase
*base
= (struct LibBase
*)PrometheusBase
;
494 HIDD_PCIDevice_WriteConfigLong(board
->aros_board
, offset
& ~0x3, data
);
501 /***************************************************************************
504 AROS_LH2(BOOL
, Prm_AddIntServer
,
507 AROS_LHA(PCIBoard
*, board
, A0
),
508 AROS_LHA(struct Interrupt
*, interrupt
, A1
),
511 struct Library
*, PrometheusBase
, 14, Prometheus
)
519 ***************************************************************************/
523 struct LibBase
*base
= (APTR
)PrometheusBase
;
524 BOOL success
= FALSE
;
526 /* Add AROS int to system */
528 success
= HIDD_PCIDevice_AddInterrupt(board
->aros_board
, interrupt
);
537 /***************************************************************************
540 AROS_LH2(VOID
, Prm_RemIntServer
,
543 AROS_LHA(PCIBoard
*, board
, A0
),
544 AROS_LHA(struct Interrupt
*, interrupt
, A1
),
547 struct Library
*, PrometheusBase
, 15, Prometheus
)
555 ***************************************************************************/
559 struct LibBase
*base
= (APTR
)PrometheusBase
;
562 HIDD_PCIDevice_RemoveInterrupt(board
->aros_board
, interrupt
);
569 /***************************************************************************
572 AROS_LH1(APTR
, Prm_AllocDMABuffer
,
575 AROS_LHA(ULONG
, size
, D0
),
578 struct Library
*, PrometheusBase
, 16, Prometheus
)
581 Allocate memory region accessible by PCI DMA.
584 size - Size of the region to allocate. NULL is safe
585 input, in this case the function fails.
588 A pointer to allocated region or NULL upon failure.
589 The region will always be LONG-aligned.
591 ***************************************************************************/
596 * This should be OK for any "direct" PCI bus.
597 * Note that this also relies on AllocMem()'s ability to return
598 * NULL when zero size is given.
600 return AllocMem(size
, MEMF_31BIT
);
607 /***************************************************************************
610 AROS_LH2(VOID
, Prm_FreeDMABuffer
,
613 AROS_LHA(APTR
, buffer
, A0
),
614 AROS_LHA(ULONG
, size
, D0
),
617 struct Library
*, PrometheusBase
, 17, Prometheus
)
620 Free memory buffer allocated by Prm_AllocDMABuffer().
623 buffer - a pointer to a buffer to free. NULL is a safe value,
624 in this case the function does nothing.
625 size - size of the buffer. Zero is a safe value, in this case
626 the function does nothing.
631 ***************************************************************************/
636 * Note that this relies on FreeMem()'s ability to ignore
637 * zero buffer or size.
639 FreeMem(buffer
, size
);
646 /***************************************************************************
649 AROS_LH1(APTR
, Prm_GetPhysicalAddr
,
652 AROS_LHA(APTR
, address
, D0
),
655 struct Library
*, PrometheusBase
, 18, Prometheus
)
663 ***************************************************************************/
667 struct LibBase
*base
= (struct LibBase
*)PrometheusBase
;
669 /* This should be OK for any "direct" PCI bus */
670 return KrnVirtualToPhysical(address
);