示例#1
0
文件: pci.c 项目: 3a9LL/panda
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.  */
}
示例#2
0
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);
}
示例#3
0
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;
}
示例#4
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;
}