Changeset 3a5909f in mainline for uspace/srv/drivers/pciintel/pci.c
- Timestamp:
- 2010-04-09T11:46:56Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3843ecb
- Parents:
- d1fc8f0
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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)) {
Note:
See TracChangeset
for help on using the changeset viewer.