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; } }
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(); }
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(); }
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; }
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(); }
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(); }