3 * - By John Hodge (thePowersGang)
9 #include <udi_physio.h>
12 #include <drv_pci.h> // acess
13 #include "../udi_internal.h"
16 /* Copied from http://projectudi.cvs.sourceforge.net/viewvc/projectudi/udiref/driver/udi_dpt/udi_dpt.h */
17 #define DPT_SET_ATTR_BOOLEAN(attr, name, val) \
18 udi_strcpy((attr)->attr_name, (name)); \
19 (attr)->attr_type = UDI_ATTR_BOOLEAN; \
20 (attr)->attr_length = sizeof(udi_boolean_t); \
21 UDI_ATTR32_SET((attr)->attr_value, (val))
23 #define DPT_SET_ATTR32(attr, name, val) \
24 udi_strcpy((attr)->attr_name, (name)); \
25 (attr)->attr_type = UDI_ATTR_UBIT32; \
26 (attr)->attr_length = sizeof(udi_ubit32_t); \
27 UDI_ATTR32_SET((attr)->attr_value, (val))
29 #define DPT_SET_ATTR_ARRAY8(attr, name, val, len) \
30 udi_strcpy((attr)->attr_name, (name)); \
31 (attr)->attr_type = UDI_ATTR_ARRAY8; \
32 (attr)->attr_length = (len); \
33 udi_memcpy((attr)->attr_value, (val), (len))
35 #define DPT_SET_ATTR_STRING(attr, name, val, len) \
36 udi_strcpy((attr)->attr_name, (name)); \
37 (attr)->attr_type = UDI_ATTR_STRING; \
38 (attr)->attr_length = (len); \
39 udi_strncpy_rtrim((char *)(attr)->attr_value, (val), (len))
45 udi_init_context_t init_context;
51 void pci_usage_ind(udi_usage_cb_t *cb, udi_ubit8_t resource_level);
52 void pci_enumerate_req(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level);
53 void pci_devmgmt_req(udi_mgmt_cb_t *cb, udi_ubit8_t mgmt_op, udi_ubit8_t parent_ID);
54 void pci_final_cleanup_req(udi_mgmt_cb_t *cb);
56 void pci_bridge_ch_event_ind(udi_channel_event_cb_t *cb);
57 void pci_unbind_req(udi_bus_bind_cb_t *cb);
58 void pci_bind_req_op(udi_bus_bind_cb_t *cb);
59 void pci_intr_attach_req(udi_intr_attach_cb_t *cb);
60 void pci_intr_detach_req(udi_intr_detach_cb_t *cb);
62 // - Hook to physio (UDI doesn't define these)
63 int pci_pio_get_regset(udi_cb_t *gcb, udi_ubit32_t regset_idx, void **baseptr, size_t *lenptr);
66 void pci_usage_ind(udi_usage_cb_t *cb, udi_ubit8_t resource_level)
68 pci_rdata_t *rdata = UDI_GCB(cb)->context;
76 switch(resource_level)
78 case UDI_RESOURCES_CRITICAL:
79 case UDI_RESOURCES_LOW:
80 case UDI_RESOURCES_NORMAL:
81 case UDI_RESOURCES_PLENTIFUL:
85 // TODO: Initialise rdata
90 void pci_enumerate_req(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level)
92 pci_rdata_t *rdata = UDI_GCB(cb)->context;
93 switch(enumeration_level)
95 case UDI_ENUMERATE_START:
96 case UDI_ENUMERATE_START_RESCAN:
98 case UDI_ENUMERATE_NEXT:
100 if( (rdata->cur_iter = PCI_GetDeviceByClass(0,0, rdata->cur_iter)) == -1 )
102 udi_enumerate_ack(cb, UDI_ENUMERATE_DONE, 0);
106 udi_instance_attr_list_t *attr_list = cb->attr_list;
109 PCI_GetDeviceInfo(rdata->cur_iter, &ven, &dev, &class);
111 PCI_GetDeviceVersion(rdata->cur_iter, &revision);
113 PCI_GetDeviceSubsys(rdata->cur_iter, &sven, &sdev);
115 udi_strcpy(attr_list->attr_name, "identifier");
116 attr_list->attr_length = sprintf((char*)attr_list->attr_value,
117 "%04x%04x%02x%04x%04x",
118 ven, dev, revision, sven, sdev);
120 DPT_SET_ATTR_STRING(attr_list, "bus_type", "pci", 3);
122 DPT_SET_ATTR32(attr_list, "pci_vendor_id", ven);
124 DPT_SET_ATTR32(attr_list, "pci_device_id", dev);
127 cb->attr_valid_length = attr_list - cb->attr_list;
128 cb->child_ID = rdata->cur_iter;
129 udi_enumerate_ack(cb, UDI_ENUMERATE_OK, 1);
134 void pci_devmgmt_req(udi_mgmt_cb_t *cb, udi_ubit8_t mgmt_op, udi_ubit8_t parent_ID)
138 void pci_final_cleanup_req(udi_mgmt_cb_t *cb)
143 void pci_bridge_ch_event_ind(udi_channel_event_cb_t *cb)
147 void pci_bind_req(udi_bus_bind_cb_t *cb)
149 // TODO: "Lock" PCI device
151 // TODO: DMA constraints
152 udi_bus_bind_ack(cb, 0, UDI_DMA_LITTLE_ENDIAN, UDI_OK);
154 void pci_unbind_req(udi_bus_bind_cb_t *cb)
158 void pci_intr_attach_req(udi_intr_attach_cb_t *cb)
161 //udi_channel_spawn(, UCI_GCB(cb), cb->gcb.channel, 0, PCI_OPS_IRQ, NULL);
164 void pci_intr_detach_req(udi_intr_detach_cb_t *cb)
170 udi_status_t pci_pio_do_io(uint32_t child_ID, udi_ubit32_t regset_idx, udi_ubit32_t ofs, udi_ubit8_t len,
171 void *data, bool isOutput)
173 tPCIDev pciid = child_ID;
174 // TODO: Cache child mappings
178 case UDI_PCI_CONFIG_SPACE:
180 return UDI_STAT_NOT_SUPPORTED;
181 case UDI_PCI_BAR_0 ... UDI_PCI_BAR_5: {
182 Uint64 bar = PCI_GetBAR(pciid, regset_idx);
187 #define _IO(fc, type) do {\
188 if( isOutput ) out##fc(bar+ofs, *(type*)data); \
189 else *(type*)data = in##fc(bar+ofs); \
193 case UDI_PIO_1BYTE: _IO(b, udi_ubit8_t); return UDI_OK;
194 case UDI_PIO_2BYTE: _IO(w, udi_ubit16_t); return UDI_OK;
195 case UDI_PIO_4BYTE: _IO(d, udi_ubit32_t); return UDI_OK;
196 //case UDI_PIO_8BYTE: _IO(q, uint64_t); return UDI_OK;
198 return UDI_STAT_NOT_SUPPORTED;
205 bar = PCI_GetValidBAR(pciid, regset_idx, PCI_BARTYPE_MEM);
206 return UDI_STAT_NOT_SUPPORTED;
210 return UDI_STAT_NOT_UNDERSTOOD;
214 // === UDI Functions ===
215 udi_mgmt_ops_t pci_mgmt_ops = {
219 pci_final_cleanup_req
221 udi_ubit8_t pci_mgmt_op_flags[4] = {0,0,0,0};
222 udi_bus_bridge_ops_t pci_bridge_ops = {
223 pci_bridge_ch_event_ind,
229 udi_ubit8_t pci_bridge_op_flags[5] = {0,0,0,0,0};
230 udi_primary_init_t pci_pri_init = {
231 .mgmt_ops = &pci_mgmt_ops,
232 .mgmt_op_flags = pci_mgmt_op_flags,
233 .mgmt_scratch_requirement = 0,
234 .enumeration_attr_list_length = 4,
235 .rdata_size = sizeof(pci_rdata_t),
236 .child_data_size = 0,
237 .per_parent_paths = 0
239 udi_ops_init_t pci_ops_list[] = {
241 1, 1, UDI_BUS_BRIDGE_OPS_NUM,
242 sizeof(udi_child_chan_context_t),
243 (udi_ops_vector_t*)&pci_bridge_ops,
248 udi_init_t pci_init = {
249 .primary_init_info = &pci_pri_init,
250 .ops_init_list = pci_ops_list
252 const char pci_udiprops[] =
253 "properties_version 0x101\0"
254 "message 1 Acess2 Kernel\0"
256 "message 3 Acess2 PCI Bus\0"
261 "shortname acesspci\0"
262 "requires udi 0x101\0"
263 "provides udi_bridge 0x101\0"
264 "meta 1 udi_bridge\0"
265 "enumerates 4 0 100 1 bus_name string pci\0"
267 "child_bind_ops 1 0 1\0"
269 size_t pci_udiprops_size = sizeof(pci_udiprops);