static void pci_setup_device(int bdf, uint32_t *p_io_base, uint32_t *p_mem_base) { int vendor_id, device_id, class_id, region; vendor_id = pci_config_readw(bdf, PCI_VENDOR_ID); device_id = pci_config_readw(bdf, PCI_DEVICE_ID); class_id = pci_config_readw(bdf, PCI_CLASS_DEVICE); printf("PCI: %02x:%02x:%x class %04x id %04x:%04x\r\n", PCI_BUS(bdf), PCI_SLOT(bdf), PCI_FUNC(bdf), class_id, vendor_id, device_id); for (region = 0; region < PCI_REGION_ROM; region++) { int ofs = PCI_BASE_ADDRESS_0 + region * 4; uint32_t old, mask, val, size, align; uint32_t *p_base; old = pci_config_readl(bdf, ofs); if (old & PCI_BASE_ADDRESS_SPACE_IO) { mask = PCI_BASE_ADDRESS_IO_MASK; p_base = p_io_base; } else { mask = PCI_BASE_ADDRESS_MEM_MASK; p_base = p_mem_base; } pci_config_writel(bdf, ofs, -1); val = pci_config_readl(bdf, ofs); pci_config_writel(bdf, ofs, old); align = size = ~(val & mask) + 1; if (val != 0) { uint32_t addr = *p_base; addr = (addr + align - 1) & ~(align - 1); *p_base = addr + size; pci_config_writel(bdf, ofs, addr); printf("PCI: region %d: %08x\r\n", region, addr); if ((val & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) { pci_config_writel(bdf, ofs + 4, 0); region++; } } } pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_IO | PCI_COMMAND_MEMORY); /* Map the interrupt. */ }
void ohci_init(void *data) { if (! CONFIG_USB_OHCI) return; struct usb_s *cntl = data; // XXX - don't call pci_config_XXX from a thread cntl->type = USB_TYPE_OHCI; u32 baseaddr = pci_config_readl(cntl->bdf, PCI_BASE_ADDRESS_0); cntl->ohci.regs = (void*)(baseaddr & PCI_BASE_ADDRESS_MEM_MASK); dprintf(3, "OHCI init on dev %02x:%02x.%x (regs=%p)\n" , pci_bdf_to_bus(cntl->bdf), pci_bdf_to_dev(cntl->bdf) , pci_bdf_to_fn(cntl->bdf), cntl->ohci.regs); // Enable bus mastering and memory access. pci_config_maskw(cntl->bdf, PCI_COMMAND , 0, PCI_COMMAND_MASTER|PCI_COMMAND_MEMORY); // XXX - check for and disable SMM control? // Disable interrupts writel(&cntl->ohci.regs->intrdisable, ~0); writel(&cntl->ohci.regs->intrstatus, ~0); // Allocate memory struct ohci_hcca *hcca = memalign_high(256, sizeof(*hcca)); struct ohci_ed *control_ed = malloc_high(sizeof(*control_ed)); if (!hcca || !control_ed) { dprintf(1, "No ram for ohci init\n"); return; } memset(hcca, 0, sizeof(*hcca)); memset(control_ed, 0, sizeof(*control_ed)); control_ed->hwINFO = ED_SKIP; cntl->ohci.control_ed = control_ed; int ret = start_ohci(cntl, hcca); if (ret) goto err; int count = check_ohci_ports(cntl); if (! count) goto err; return; err: stop_ohci(cntl); free(hcca); free(control_ed); }
int ehci_init(struct pci_device *pci, int busid, struct pci_device *comppci) { if (! CONFIG_USB_EHCI) return -1; u16 bdf = pci->bdf; u32 baseaddr = pci_config_readl(bdf, PCI_BASE_ADDRESS_0); struct ehci_caps *caps = (void*)(baseaddr & PCI_BASE_ADDRESS_MEM_MASK); u32 hcc_params = readl(&caps->hccparams); if (hcc_params & HCC_64BIT_ADDR) { dprintf(1, "No support for 64bit EHCI\n"); return -1; } struct usb_ehci_s *cntl = malloc_tmphigh(sizeof(*cntl)); if (!cntl) { warn_noalloc(); return -1; } memset(cntl, 0, sizeof(*cntl)); cntl->usb.busid = busid; cntl->usb.pci = pci; cntl->usb.type = USB_TYPE_EHCI; cntl->caps = caps; cntl->regs = (void*)caps + readb(&caps->caplength); dprintf(1, "EHCI init on dev %02x:%02x.%x (regs=%p)\n" , pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf) , pci_bdf_to_fn(bdf), cntl->regs); pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_MASTER); // XXX - check for and disable SMM control? // Find companion controllers. int count = 0; for (;;) { if (!comppci || comppci == pci) break; if (pci_classprog(comppci) == PCI_CLASS_SERIAL_USB_UHCI) cntl->companion[count++] = comppci; else if (pci_classprog(comppci) == PCI_CLASS_SERIAL_USB_OHCI) cntl->companion[count++] = comppci; comppci = comppci->next; } run_thread(configure_ehci, cntl); return 0; }
static void init_pvscsi(struct pci_device *pci) { struct pvscsi_ring_dsc_s *ring_dsc = NULL; int i; u16 bdf = pci->bdf; void *iobase = (void*)(pci_config_readl(pci->bdf, PCI_BASE_ADDRESS_0) & PCI_BASE_ADDRESS_MEM_MASK); pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_MASTER); dprintf(1, "found pvscsi at %02x:%02x.%x, io @ %p\n", pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf), iobase); pvscsi_write_cmd_desc(iobase, PVSCSI_CMD_ADAPTER_RESET, NULL, 0); pvscsi_init_rings(iobase, &ring_dsc); for (i = 0; i < 7; i++) pvscsi_scan_target(pci, iobase, ring_dsc, i); return; }