Changeset 3a5909f in mainline
- Timestamp:
- 2010-04-09T11:46:56Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3843ecb
- Parents:
- d1fc8f0
- Location:
- uspace
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libc/include/ipc/dev_iface.h
rd1fc8f0 r3a5909f 60 60 typedef enum { 61 61 INTERRUPT, 62 REGISTER 62 IO_RANGE, 63 MEM_RANGE 63 64 } hw_res_type_t; 64 65 … … 76 77 endianness_t endianness; 77 78 size_t size; 78 } reg; 79 } mem_range; 80 struct { 81 uint64_t address; 82 endianness_t endianness; 83 size_t size; 84 } io_range; 79 85 struct { 80 86 int irq; 81 } int r;87 } interrupt; 82 88 } res; 83 89 } hw_resource_t; -
uspace/srv/drivers/pciintel/pci.c
rd1fc8f0 r3a5909f 55 55 56 56 #include "pci.h" 57 #include "pci_regs.h"58 57 59 58 #define NAME "pciintel" … … 181 180 void pci_conf_write_8(device_t *dev, int reg, uint8_t val) 182 181 { 183 pci_conf_write(dev, reg, (uint8_t *)&val, 4);182 pci_conf_write(dev, reg, (uint8_t *)&val, 1); 184 183 } 185 184 186 185 void pci_conf_write_16(device_t *dev, int reg, uint16_t val) 187 186 { 188 pci_conf_write(dev, reg, (uint8_t *)&val, 4);187 pci_conf_write(dev, reg, (uint8_t *)&val, 2); 189 188 } 190 189 … … 208 207 } 209 208 210 211 static size_t range_size_form_mask(uint32_t mask) 212 { 213 // TODO 214 return 0; 215 } 209 void pci_add_range(device_t *dev, uint64_t range_addr, size_t range_size, bool io) 210 { 211 pci_dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data; 212 hw_resource_list_t *hw_res_list = &dev_data->hw_resources; 213 hw_resource_t *hw_resources = hw_res_list->resources; 214 size_t count = hw_res_list->count; 215 216 assert(NULL != hw_resources); 217 assert(count < PCI_MAX_HW_RES); 218 219 if (io) { 220 hw_resources[count].type = IO_RANGE; 221 hw_resources[count].res.io_range.address = range_addr; 222 hw_resources[count].res.io_range.size = range_size; 223 hw_resources[count].res.io_range.endianness = LITTLE_ENDIAN; 224 } else { 225 hw_resources[count].type = MEM_RANGE; 226 hw_resources[count].res.mem_range.address = range_addr; 227 hw_resources[count].res.mem_range.size = range_size; 228 hw_resources[count].res.mem_range.endianness = LITTLE_ENDIAN; 229 } 230 231 hw_res_list->count++; 232 } 233 216 234 217 235 /** Read the base address register (BAR) of the device … … 223 241 * @return the addr the address of the BAR which should be read next. 224 242 */ 225 staticint pci_read_bar(device_t *dev, int addr)243 int pci_read_bar(device_t *dev, int addr) 226 244 { 227 245 // value of the BAR … … 237 255 uint64_t range_addr; 238 256 239 257 // get the value of the BAR 240 258 val = pci_conf_read_32(dev, addr); 241 259 … … 263 281 // restore the original value 264 282 pci_conf_write_32(dev, addr, val); 265 266 range_size = range_size_form_mask(mask); 283 val = pci_conf_read_32(dev, addr); 284 285 range_size = pci_bar_mask_to_size(mask); 267 286 268 287 if (w64) { … … 272 291 } 273 292 if (0 != range_addr) { 274 printf(NAME ": device address = %x\n", range_addr); 275 } 276 277 // TODO add to the HW resource list 293 printf(NAME ": device %s : ", dev->name); 294 printf("address = %x", range_addr); 295 printf(", size = %x\n", range_size); 296 } 297 298 pci_add_range(dev, range_addr, range_size, io); 278 299 279 300 if (w64) { … … 283 304 } 284 305 285 /** Read the base address registers (BARs) of the device 286 * and adds the addresses to its hw resource list. 287 * 288 * @param dev the pci device. 289 */ 290 static void pci_read_bars(device_t *dev) 291 { 292 // position of the BAR in the PCI configuration address space of the device 293 int addr = PCI_BASE_ADDR_0; 294 295 while (addr <= PCI_BASE_ADDR_5) { 296 addr = pci_read_bar(dev, addr); 306 void pci_add_interrupt(device_t *dev, int irq) 307 { 308 pci_dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data; 309 hw_resource_list_t *hw_res_list = &dev_data->hw_resources; 310 hw_resource_t *hw_resources = hw_res_list->resources; 311 size_t count = hw_res_list->count; 312 313 assert(NULL != hw_resources); 314 assert(count < PCI_MAX_HW_RES); 315 316 hw_resources[count].type = INTERRUPT; 317 hw_resources[count].res.interrupt.irq = irq; 318 319 hw_res_list->count++; 320 321 322 printf(NAME ": device %s uses irq %x.\n", dev->name, irq); 323 } 324 325 void pci_read_interrupt(device_t *dev) 326 { 327 uint8_t irq = pci_conf_read_8(dev, PCI_BRIDGE_INT_LINE); 328 if (0xff != irq) { 329 pci_add_interrupt(dev, irq); 297 330 } 298 331 } … … 321 354 dev_data->vendor_id = pci_conf_read_16(dev, PCI_VENDOR_ID); 322 355 dev_data->device_id = pci_conf_read_16(dev, PCI_DEVICE_ID); 323 if (dev_data->vendor_id == 0x FFFF) { // device is not present, go on scanning the bus356 if (dev_data->vendor_id == 0xffff) { // device is not present, go on scanning the bus 324 357 if (fnum == 0) { 325 358 break; … … 334 367 header_type = header_type & 0x7F; // clear the multifunction bit 335 368 336 // TODO initialize device - interfaces, hw resources 369 create_pci_dev_name(dev); 370 371 pci_alloc_resource_list(dev); 337 372 pci_read_bars(dev); 338 339 create_pci_dev_name(dev); 373 pci_read_interrupt(dev); 374 375 // TODO initialize device interfaces 376 340 377 printf(NAME ": adding new child device %s.\n", dev->name); 341 378 342 379 create_pci_match_ids(dev); 343 380 344 if (!child_device_register(dev, parent)) { 381 if (!child_device_register(dev, parent)) { 382 pci_clean_resource_list(dev); 345 383 clean_match_ids(&dev->match_ids); 346 384 free((char *)dev->name); … … 366 404 } 367 405 368 if (dev_data->vendor_id == 0x FFFF) {406 if (dev_data->vendor_id == 0xffff) { 369 407 delete_device(dev); 370 408 delete_pci_dev_data(dev_data); // free the auxiliary device structure 371 } 372 409 } 373 410 } 374 411 … … 397 434 ipc_hangup(dev->parent_phone); 398 435 return false; 399 } 400 401 402 printf(NAME ": conf_addr = %x.\n", hw_resources.resources[0].res.reg.address); 436 } 437 438 printf(NAME ": conf_addr = %x.\n", hw_resources.resources[0].res.io_range.address); 403 439 404 440 assert(hw_resources.count > 0); 405 assert(hw_resources.resources[0].type == REGISTER);406 assert(hw_resources.resources[0].res. reg.size == 8);407 408 bus_data->conf_io_addr = (uint32_t)hw_resources.resources[0].res. reg.address;441 assert(hw_resources.resources[0].type == IO_RANGE); 442 assert(hw_resources.resources[0].res.io_range.size == 8); 443 444 bus_data->conf_io_addr = (uint32_t)hw_resources.resources[0].res.io_range.address; 409 445 410 446 if (pio_enable((void *)bus_data->conf_io_addr, 8, &bus_data->conf_addr_port)) { -
uspace/srv/drivers/pciintel/pci.h
rd1fc8f0 r3a5909f 41 41 #include <malloc.h> 42 42 43 #include "pci_regs.h" 44 45 #define PCI_MAX_HW_RES 8 46 43 47 typedef struct pci_dev_data { 44 48 int bus; … … 49 53 hw_resource_list_t hw_resources; 50 54 } pci_dev_data_t; 55 56 void create_pci_match_ids(device_t *dev); 57 58 uint8_t pci_conf_read_8(device_t *dev, int reg); 59 uint16_t pci_conf_read_16(device_t *dev, int reg); 60 uint32_t pci_conf_read_32(device_t *dev, int reg); 61 void pci_conf_write_8(device_t *dev, int reg, uint8_t val); 62 void pci_conf_write_16(device_t *dev, int reg, uint16_t val); 63 void pci_conf_write_32(device_t *dev, int reg, uint32_t val); 64 65 void pci_add_range(device_t *dev, uint64_t range_addr, size_t range_size, bool io); 66 int pci_read_bar(device_t *dev, int addr); 67 void pci_read_interrupt(device_t *dev); 68 void pci_add_interrupt(device_t *dev, int irq); 69 70 void pci_bus_scan(device_t *parent, int bus_num); 71 51 72 52 73 static inline pci_dev_data_t *create_pci_dev_data() … … 82 103 } 83 104 84 void create_pci_match_ids(device_t *dev); 105 static inline bool pci_alloc_resource_list(device_t *dev) 106 { 107 pci_dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data; 108 dev_data->hw_resources.resources = (hw_resource_t *)malloc(PCI_MAX_HW_RES * sizeof(hw_resource_t)); 109 return dev_data->hw_resources.resources != NULL; 110 } 85 111 86 uint8_t pci_conf_read_8(device_t *dev, int reg); 87 uint16_t pci_conf_read_16(device_t *dev, int reg); 88 uint32_t pci_conf_read_32(device_t *dev, int reg); 89 void pci_conf_write_8(device_t *dev, int reg, uint8_t val); 90 void pci_conf_write_16(device_t *dev, int reg, uint16_t val); 91 void pci_conf_write_32(device_t *dev, int reg, uint32_t val); 112 static inline bool pci_clean_resource_list(device_t *dev) 113 { 114 pci_dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data; 115 if (NULL != dev_data->hw_resources.resources) { 116 free(dev_data->hw_resources.resources); 117 dev_data->hw_resources.resources = NULL; 118 } 119 } 92 120 93 void pci_bus_scan(device_t *parent, int bus_num); 121 /** Read the base address registers (BARs) of the device 122 * and adds the addresses to its hw resource list. 123 * 124 * @param dev the pci device. 125 */ 126 static inline void pci_read_bars(device_t *dev) 127 { 128 // position of the BAR in the PCI configuration address space of the device 129 int addr = PCI_BASE_ADDR_0; 130 131 while (addr <= PCI_BASE_ADDR_5) { 132 addr = pci_read_bar(dev, addr); 133 } 134 } 135 136 static inline size_t pci_bar_mask_to_size(uint32_t mask) 137 { 138 return ((mask & 0xfffffff0) ^ 0xffffffff) + 1; 139 } 140 94 141 95 142 #endif -
uspace/srv/drivers/rootia32/rootia32.c
rd1fc8f0 r3a5909f 75 75 76 76 static hw_resource_t pci_conf_regs = { 77 .type = REGISTER,78 .res. reg= {79 .address = (void *)0xCF8,77 .type = IO_RANGE, 78 .res.io_range = { 79 .address = 0xCF8, 80 80 .size = 8, 81 81 .endianness = LITTLE_ENDIAN
Note:
See TracChangeset
for help on using the changeset viewer.