Exemplo n.º 1
0
void
ehci_free_pipe(struct usb_pipe *p)
{
    if (! CONFIG_USB_EHCI)
        return;
    dprintf(7, "ehci_free_pipe %p\n", p);
    struct ehci_pipe *pipe = container_of(p, struct ehci_pipe, pipe);
    struct usb_ehci_s *cntl = container_of(
        pipe->pipe.cntl, struct usb_ehci_s, usb);

    struct ehci_qh *start = cntl->async_qh;
    struct ehci_qh *pos = start;
    for (;;) {
        struct ehci_qh *next = (void*)(pos->next & ~EHCI_PTR_BITS);
        if (next == start) {
            // Not found?!  Exit without freeing.
            warn_internalerror();
            return;
        }
        if (next == &pipe->qh) {
            pos->next = next->next;
            ehci_waittick(cntl);
            free(pipe);
            return;
        }
        pos = next;
    }
}
Exemplo n.º 2
0
static void romfile_loader_add_pointer(struct romfile_loader_entry_s *entry,
                                       struct romfile_loader_files *files)
{
    struct romfile_loader_file *dest_file;
    struct romfile_loader_file *src_file;
    unsigned offset = le32_to_cpu(entry->pointer_offset);
    u64 pointer = 0;

    dest_file = romfile_loader_find(entry->pointer_dest_file, files);
    src_file = romfile_loader_find(entry->pointer_src_file, files);

    if (!dest_file || !src_file || !dest_file->data || !src_file->data ||
        offset + entry->pointer_size < offset ||
        offset + entry->pointer_size > dest_file->file->size ||
        entry->pointer_size < 1 || entry->pointer_size > 8 ||
        entry->pointer_size & (entry->pointer_size - 1))
        goto err;

    memcpy(&pointer, dest_file->data + offset, entry->pointer_size);
    pointer = le64_to_cpu(pointer);
    pointer += (unsigned long)src_file->data;
    pointer = cpu_to_le64(pointer);
    memcpy(dest_file->data + offset, &pointer, entry->pointer_size);

    return;
err:
    warn_internalerror();
}
Exemplo n.º 3
0
void
qemu_platform_setup(void)
{
    if (!CONFIG_QEMU)
        return;

    if (runningOnXen()) {
        pci_probe_devices();
        xen_hypercall_setup();
        xen_biostable_setup();
        return;
    }

    // Initialize pci
    pci_setup();
    smm_device_setup();
    smm_setup();

    // Initialize mtrr and smp
    mtrr_setup();
    smp_setup();

    // Create bios tables
    pirtable_setup();
    mptable_setup();
    smbios_setup();

    if (CONFIG_FW_ROMFILE_LOAD) {
        int loader_err;

        dprintf(3, "load ACPI tables\n");

        loader_err = romfile_loader_execute("etc/table-loader");

        RsdpAddr = find_acpi_rsdp();

        if (RsdpAddr)
            return;

        /* If present, loader should have installed an RSDP.
         * Not installed? We might still be able to continue
         * using the builtin RSDP.
         */
        if (!loader_err)
            warn_internalerror();
    }

    acpi_setup();
}
Exemplo n.º 4
0
int romfile_loader_execute(const char *name)
{
    struct romfile_loader_entry_s *entry;
    int size, offset = 0, nfiles;
    struct romfile_loader_files *files;
    void *data = romfile_loadfile(name, &size);
    if (!data)
        return -1;

    if (size % sizeof(*entry)) {
        warn_internalerror();
        goto err;
    }

    /* (over)estimate the number of files to load. */
    nfiles = size / sizeof(*entry);
    files = malloc_tmp(sizeof(*files) + nfiles * sizeof(files->files[0]));
    if (!files) {
        warn_noalloc();
        goto err;
    }
    files->nfiles = 0;

    for (offset = 0; offset < size; offset += sizeof(*entry)) {
        entry = data + offset;
        switch (le32_to_cpu(entry->command)) {
                case ROMFILE_LOADER_COMMAND_ALLOCATE:
                        romfile_loader_allocate(entry, files);
                        break;
                case ROMFILE_LOADER_COMMAND_ADD_POINTER:
                        romfile_loader_add_pointer(entry, files);
                        break;
                case ROMFILE_LOADER_COMMAND_ADD_CHECKSUM:
                        romfile_loader_add_checksum(entry, files);
                default:
                        /* Skip commands that we don't recognize. */
                        break;
        }
    }

    free(files);
    free(data);
    return 0;

err:
    free(data);
    return -1;
}
Exemplo n.º 5
0
static void romfile_loader_allocate(struct romfile_loader_entry_s *entry,
                                    struct romfile_loader_files *files)
{
    struct zone_s *zone;
    struct romfile_loader_file *file = &files->files[files->nfiles];
    void *data;
    int ret;
    unsigned alloc_align = le32_to_cpu(entry->alloc_align);

    if (alloc_align & (alloc_align - 1))
        goto err;

    switch (entry->alloc_zone) {
        case ROMFILE_LOADER_ALLOC_ZONE_HIGH:
            zone = &ZoneHigh;
            break;
        case ROMFILE_LOADER_ALLOC_ZONE_FSEG:
            zone = &ZoneFSeg;
            break;
        default:
            goto err;
    }
    if (alloc_align < MALLOC_MIN_ALIGN)
        alloc_align = MALLOC_MIN_ALIGN;
    if (entry->alloc_file[ROMFILE_LOADER_FILESZ - 1])
        goto err;
    file->file = romfile_find(entry->alloc_file);
    if (!file->file || !file->file->size)
        return;
    data = _malloc(zone, MALLOC_DEFAULT_HANDLE, file->file->size, alloc_align);
    if (!data) {
        warn_noalloc();
        return;
    }
    ret = file->file->copy(file->file, data, file->file->size);
    if (ret != file->file->size)
        goto file_err;
    file->data = data;
    files->nfiles++;
    return;

file_err:
    free(data);
err:
    warn_internalerror();
}
Exemplo n.º 6
0
static void romfile_loader_add_checksum(struct romfile_loader_entry_s *entry,
                                        struct romfile_loader_files *files)
{
    struct romfile_loader_file *file;
    unsigned offset = le32_to_cpu(entry->cksum_offset);
    unsigned start = le32_to_cpu(entry->cksum_start);
    unsigned len = le32_to_cpu(entry->cksum_length);
    u8 *data;

    file = romfile_loader_find(entry->cksum_file, files);

    if (!file || !file->data || offset >= file->file->size ||
        start + len < start || start + len > file->file->size)
        goto err;

    data = file->data + offset;
    *data -= checksum(file->data + start, len);

    return;
err:
    warn_internalerror();
}