コード例 #1
0
static int
pvscsi_add_lun(struct pci_device *pci, void *iobase,
               struct pvscsi_ring_dsc_s *ring_dsc, u8 target, u8 lun)
{
    struct pvscsi_lun_s *plun = malloc_fseg(sizeof(*plun));
    if (!plun) {
        warn_noalloc();
        return -1;
    }
    memset(plun, 0, sizeof(*plun));
    plun->drive.type = DTYPE_PVSCSI;
    plun->drive.cntl_id = pci->bdf;
    plun->target = target;
    plun->lun = lun;
    plun->iobase = iobase;
    plun->ring_dsc = ring_dsc;

    char *name = znprintf(16, "pvscsi %02x:%02x.%x %d:%d",
                          pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf),
                          pci_bdf_to_fn(pci->bdf), target, lun);
    int prio = bootprio_find_scsi_device(pci, target, lun);
    int ret = scsi_drive_setup(&plun->drive, name, prio);
    free(name);
    if (ret)
        goto fail;
    return 0;

fail:
    free(plun);
    return -1;
}
コード例 #2
0
ファイル: usb-ohci.c プロジェクト: TheLoneRanger14/vmxray
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
ファイル: usb-ehci.c プロジェクト: floren/seabios-kvm
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
ファイル: pcibios.c プロジェクト: joshsyu/PQEMU
// installation check
static void
handle_1ab101(struct bregs *regs)
{
    // Find max bus.
    int bdf, max;
    foreachpci(bdf, max) {
    }

    regs->al = 0x01; // Flags - "Config Mechanism #1" supported.
    regs->bx = 0x0210; // PCI version 2.10
    regs->cl = pci_bdf_to_bus(max - 1);
    regs->edx = 0x20494350; // "PCI "
    // XXX - bochs bios code sets edi to point to 32bit code - but no
    // reference to this in spec.
    set_code_success(regs);
}
コード例 #5
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;
}
コード例 #6
0
ファイル: disk.c プロジェクト: joshsyu/PQEMU
// IBM/MS get drive parameters
static void
disk_1348(struct bregs *regs, struct drive_s *drive_g)
{
    u16 size = GET_INT13DPT(regs, size);

    // Buffer is too small
    if (size < 26) {
        disk_ret(regs, DISK_RET_EPARAM);
        return;
    }

    // EDD 1.x

    u8  type    = GET_GLOBAL(drive_g->type);
    u16 npc     = GET_GLOBAL(drive_g->pchs.cylinders);
    u16 nph     = GET_GLOBAL(drive_g->pchs.heads);
    u16 npspt   = GET_GLOBAL(drive_g->pchs.spt);
    u64 lba     = GET_GLOBAL(drive_g->sectors);
    u16 blksize = GET_GLOBAL(drive_g->blksize);

    dprintf(DEBUG_HDL_13, "disk_1348 size=%d t=%d chs=%d,%d,%d lba=%d bs=%d\n"
            , size, type, npc, nph, npspt, (u32)lba, blksize);

    SET_INT13DPT(regs, size, 26);
    if (type == DTYPE_ATAPI) {
        // 0x74 = removable, media change, lockable, max values
        SET_INT13DPT(regs, infos, 0x74);
        SET_INT13DPT(regs, cylinders, 0xffffffff);
        SET_INT13DPT(regs, heads, 0xffffffff);
        SET_INT13DPT(regs, spt, 0xffffffff);
        SET_INT13DPT(regs, sector_count, (u64)-1);
    } else {
        if (lba > (u64)npspt*nph*0x3fff) {
            SET_INT13DPT(regs, infos, 0x00); // geometry is invalid
            SET_INT13DPT(regs, cylinders, 0x3fff);
        } else {
            SET_INT13DPT(regs, infos, 0x02); // geometry is valid
            SET_INT13DPT(regs, cylinders, (u32)npc);
        }
        SET_INT13DPT(regs, heads, (u32)nph);
        SET_INT13DPT(regs, spt, (u32)npspt);
        SET_INT13DPT(regs, sector_count, lba);
    }
    SET_INT13DPT(regs, blksize, blksize);

    if (size < 30 || (type != DTYPE_ATA && type != DTYPE_ATAPI)) {
        disk_ret(regs, DISK_RET_SUCCESS);
        return;
    }

    // EDD 2.x

    u16 ebda_seg = get_ebda_seg();
    SET_INT13DPT(regs, size, 30);

    SET_INT13DPT(regs, dpte_segment, ebda_seg);
    SET_INT13DPT(regs, dpte_offset
                 , offsetof(struct extended_bios_data_area_s, dpte));

    // Fill in dpte
    u8 ataid = GET_GLOBAL(drive_g->cntl_id);
    u8 channel = ataid / 2;
    u8 slave = ataid % 2;
    u16 iobase1 = GET_GLOBAL(ATA_channels[channel].iobase1);
    u16 iobase2 = GET_GLOBAL(ATA_channels[channel].iobase2);
    u8 irq = GET_GLOBAL(ATA_channels[channel].irq);

    u16 options = 0;
    if (type == DTYPE_ATA) {
        u8 translation = GET_GLOBAL(drive_g->translation);
        if (translation != TRANSLATION_NONE) {
            options |= 1<<3; // CHS translation
            if (translation == TRANSLATION_LBA)
                options |= 1<<9;
            if (translation == TRANSLATION_RECHS)
                options |= 3<<9;
        }
    } else {
        // ATAPI
        options |= 1<<5; // removable device
        options |= 1<<6; // atapi device
    }
    options |= 1<<4; // lba translation
    if (CONFIG_ATA_PIO32)
        options |= 1<<7;

    SET_EBDA2(ebda_seg, dpte.iobase1, iobase1);
    SET_EBDA2(ebda_seg, dpte.iobase2, iobase2 + ATA_CB_DC);
    SET_EBDA2(ebda_seg, dpte.prefix, ((slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0)
                                      | ATA_CB_DH_LBA));
    SET_EBDA2(ebda_seg, dpte.unused, 0xcb);
    SET_EBDA2(ebda_seg, dpte.irq, irq);
    SET_EBDA2(ebda_seg, dpte.blkcount, 1);
    SET_EBDA2(ebda_seg, dpte.dma, 0);
    SET_EBDA2(ebda_seg, dpte.pio, 0);
    SET_EBDA2(ebda_seg, dpte.options, options);
    SET_EBDA2(ebda_seg, dpte.reserved, 0);
    SET_EBDA2(ebda_seg, dpte.revision, 0x11);

    u8 sum = checksum_far(
                 ebda_seg, (void*)offsetof(struct extended_bios_data_area_s, dpte), 15);
    SET_EBDA2(ebda_seg, dpte.checksum, -sum);

    if (size < 66) {
        disk_ret(regs, DISK_RET_SUCCESS);
        return;
    }

    // EDD 3.x
    SET_INT13DPT(regs, key, 0xbedd);
    SET_INT13DPT(regs, dpi_length, 36);
    SET_INT13DPT(regs, reserved1, 0);
    SET_INT13DPT(regs, reserved2, 0);

    int bdf = GET_GLOBAL(ATA_channels[channel].pci_bdf);
    if (bdf != -1) {
        SET_INT13DPT(regs, host_bus[0], 'P');
        SET_INT13DPT(regs, host_bus[1], 'C');
        SET_INT13DPT(regs, host_bus[2], 'I');
        SET_INT13DPT(regs, host_bus[3], 0);

        u32 path = (pci_bdf_to_bus(bdf) | (pci_bdf_to_dev(bdf) << 8)
                    | (pci_bdf_to_fn(bdf) << 16));
        SET_INT13DPT(regs, iface_path, path);
    } else {
        // ISA
        SET_INT13DPT(regs, host_bus[0], 'I');
        SET_INT13DPT(regs, host_bus[1], 'S');
        SET_INT13DPT(regs, host_bus[2], 'A');
        SET_INT13DPT(regs, host_bus[3], 0);

        SET_INT13DPT(regs, iface_path, iobase1);
    }

    SET_INT13DPT(regs, iface_type[0], 'A');
    SET_INT13DPT(regs, iface_type[1], 'T');
    SET_INT13DPT(regs, iface_type[2], 'A');
    SET_INT13DPT(regs, iface_type[3], 0);
    SET_INT13DPT(regs, iface_type[4], 0);
    SET_INT13DPT(regs, iface_type[5], 0);
    SET_INT13DPT(regs, iface_type[6], 0);
    SET_INT13DPT(regs, iface_type[7], 0);

    SET_INT13DPT(regs, device_path, slave);

    SET_INT13DPT(regs, checksum
                 , -checksum_far(regs->ds, (void*)(regs->si+30), 35));

    disk_ret(regs, DISK_RET_SUCCESS);
}
コード例 #7
0
ファイル: bochsvga.c プロジェクト: GrimDerp/TriforceAFL
int
bochsvga_setup(void)
{
    int ret = stdvga_setup();
    if (ret)
        return ret;

    /* Sanity checks */
    dispi_write(VBE_DISPI_INDEX_ID, VBE_DISPI_ID0);
    if (dispi_read(VBE_DISPI_INDEX_ID) != VBE_DISPI_ID0) {
        dprintf(1, "No VBE DISPI interface detected, falling back to stdvga\n");
        return 0;
    }

    dispi_write(VBE_DISPI_INDEX_ID, VBE_DISPI_ID5);
    SET_VGA(dispi_found, 1);

    if (GET_GLOBAL(HaveRunInit))
        return 0;

    u32 lfb_addr = VBE_DISPI_LFB_PHYSICAL_ADDRESS;
    int bdf = GET_GLOBAL(VgaBDF);
    if (CONFIG_VGA_PCI && bdf >= 0) {
        u16 vendor = pci_config_readw(bdf, PCI_VENDOR_ID);
        int barid;
        switch (vendor) {
        case 0x15ad: /* qemu vmware vga */
            barid = 1;
            break;
        case 0x1af4: /* virtio-vga */
            barid = 2;
            break;
        default: /* stdvga, qxl */
            barid = 0;
            break;
        }
        u32 bar = pci_config_readl(bdf, PCI_BASE_ADDRESS_0 + barid * 4);
        lfb_addr = bar & PCI_BASE_ADDRESS_MEM_MASK;
        dprintf(1, "VBE DISPI: bdf %02x:%02x.%x, bar %d\n", pci_bdf_to_bus(bdf)
                , pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf), barid);
    }

    SET_VGA(VBE_framebuffer, lfb_addr);
    u32 totalmem = dispi_read(VBE_DISPI_INDEX_VIDEO_MEMORY_64K) * 64 * 1024;
    SET_VGA(VBE_total_memory, totalmem);
    SET_VGA(VBE_win_granularity, 64);
    SET_VGA(VBE_capabilities, VBE_CAPABILITY_8BIT_DAC);

    dprintf(1, "VBE DISPI: lfb_addr=%x, size %d MB\n",
            lfb_addr, totalmem >> 20);

    // Validate modes
    u16 en = dispi_read(VBE_DISPI_INDEX_ENABLE);
    dispi_write(VBE_DISPI_INDEX_ENABLE, en | VBE_DISPI_GETCAPS);
    u16 max_xres = dispi_read(VBE_DISPI_INDEX_XRES);
    u16 max_bpp = dispi_read(VBE_DISPI_INDEX_BPP);
    dispi_write(VBE_DISPI_INDEX_ENABLE, en);
    struct bochsvga_mode *m = bochsvga_modes;
    for (; m < &bochsvga_modes[ARRAY_SIZE(bochsvga_modes)]; m++) {
        u16 width = GET_GLOBAL(m->info.width);
        u16 height = GET_GLOBAL(m->info.height);
        u8 depth = GET_GLOBAL(m->info.depth);
        u32 mem = (height * DIV_ROUND_UP(width * vga_bpp(&m->info), 8)
                   * stdvga_vram_ratio(&m->info));

        if (width > max_xres || depth > max_bpp || mem > totalmem) {
            dprintf(1, "Removing mode %x\n", GET_GLOBAL(m->mode));
            SET_VGA(m->mode, 0xffff);
        }
    }

    return 0;
}