void *Pool_malloc(Pool *self, size_t size) #endif { BlockHeader *p; BlockHeader *s; #ifdef POOL_DEBUG size_t i; size_t alloc_block_size = ALIGN_UP(HEADER_SIZE + size + WALL_SIZE * 2); #else size_t alloc_block_size = ALIGN_UP(HEADER_SIZE + size); #endif if (self->init_flag != self) { DEBUGLOG(("Pool_malloc: pool is not initialized: %s(%d)\n", file, line)); assert(0); return 0; } #ifdef POOL_DEBUG if (!size) { DEBUGLOG(("Pool_malloc: alloc 0 bytes: %s(%d)\n", file, line)); } if (self->fail_count >= 0) { if (self->fail_count > 0) { self->fail_count--; } else { DEBUGLOG(("Pool_malloc: return NULL by fail_count: %s(%d)\n", file, line)); return 0; } } #endif for (p = self->loop_p->next; p != self->loop_p; p = p->next) { if (!p->occupied && p->size >= alloc_block_size) { if (p->size >= alloc_block_size + HEADER_SIZE + SPLIT_MIN) { s = (BlockHeader *) ((char *) p + alloc_block_size); s->size = p->size - alloc_block_size; s->occupied = 0; s->magic = MAGIC_NO; p->size = alloc_block_size; s->next = p->next; #ifndef POOL_SLIST s->prev = p; p->next->prev = s; #endif p->next = s; } p->occupied = 1; #ifdef POOL_DEBUG p->file = file; p->line = line; p->alloc_size = size; for (i = 0; i < WALL_SIZE; i++) { ((char *) p)[HEADER_SIZE + i] = WALL_CHAR; ((char *) p)[HEADER_SIZE + WALL_SIZE + size + i] = WALL_CHAR; } #endif self->loop_p = p; #ifdef POOL_DEBUG return (char *) p + HEADER_SIZE + WALL_SIZE; #else return (char *) p + HEADER_SIZE; #endif } } DEBUGLOG(("Pool_malloc: return NULL: %s(%d)\n", file, line)); return 0; }
void PackArmPe::rebuildImports(upx_byte *& extrainfo) { if (ODADDR(PEDIR_IMPORT) == 0 || ODSIZE(PEDIR_IMPORT) <= sizeof(import_desc)) return; // const upx_byte * const idata = obuf + get_le32(extrainfo); OPTR_C(const upx_byte, idata, obuf + get_le32(extrainfo)); const unsigned inamespos = get_le32(extrainfo + 4); extrainfo += 8; unsigned sdllnames = 0; // const upx_byte *import = ibuf + IDADDR(PEDIR_IMPORT) - isection[2].vaddr; // const upx_byte *p; IPTR_I(const upx_byte, import, ibuf + IDADDR(PEDIR_IMPORT) - isection[2].vaddr); OPTR(const upx_byte, p); for (p = idata; get_le32(p) != 0; ++p) { const upx_byte *dname = get_le32(p) + import; ICHECK(dname, 1); const unsigned dlen = strlen(dname); ICHECK(dname, dlen + 1); sdllnames += dlen + 1; for (p += 8; *p;) if (*p == 1) p += strlen(++p) + 1; else if (*p == 0xff) p += 3; // ordinal else p += 5; } sdllnames = ALIGN_UP(sdllnames,2u); upx_byte * const Obuf = obuf - rvamin; import_desc * const im0 = (import_desc*) (Obuf + ODADDR(PEDIR_IMPORT)); import_desc *im = im0; upx_byte *dllnames = Obuf + inamespos; upx_byte *importednames = dllnames + sdllnames; upx_byte * const importednames_start = importednames; for (p = idata; get_le32(p) != 0; ++p) { // restore the name of the dll const upx_byte *dname = get_le32(p) + import; ICHECK(dname, 1); const unsigned dlen = strlen(dname); ICHECK(dname, dlen + 1); const unsigned iatoffs = get_le32(p + 4) + rvamin; if (inamespos) { // now I rebuild the dll names OCHECK(dllnames, dlen + 1); strcpy(dllnames, dname); im->dllname = ptr_diff(dllnames,Obuf); //;;;printf("\ndll: %s:",dllnames); dllnames += dlen + 1; } else { OCHECK(Obuf + im->dllname, dlen + 1); strcpy(Obuf + im->dllname, dname); } im->oft = im->iat = iatoffs; // LE32 *newiat = (LE32 *) (Obuf + iatoffs); OPTR_I(LE32, newiat, (LE32 *) (Obuf + iatoffs)); // restore the imported names+ordinals for (p += 8; *p; ++newiat) if (*p == 1) { const unsigned ilen = strlen(++p) + 1; if (inamespos) { if (ptr_diff(importednames, importednames_start) & 1) importednames -= 1; omemcpy(importednames + 2, p, ilen); //;;;printf(" %s",importednames+2); *newiat = ptr_diff(importednames, Obuf); importednames += 2 + ilen; } else { OCHECK(Obuf + *newiat + 2, ilen + 1); strcpy(Obuf + *newiat + 2, p); } p += ilen; } else if (*p == 0xff) { *newiat = get_le16(p + 1) + 0x80000000; //;;;printf(" %x",(unsigned)*newiat); p += 3; } else { *newiat = get_le32(get_le32(p + 1) + import); assert(*newiat & 0x80000000); p += 5; } *newiat = 0; im++; } //memset(idata,0,p - idata); }
void bootstrap(void) { version_print(); ofw_memmap(&bootinfo.memmap); void *bootinfo_pa = ofw_translate(&bootinfo); void *real_mode_pa = ofw_translate(&real_mode); void *loader_address_pa = ofw_translate((void *) LOADER_ADDRESS); printf("\nMemory statistics (total %llu MB)\n", bootinfo.memmap.total >> 20); printf(" %p|%p: real mode trampoline\n", &real_mode, real_mode_pa); printf(" %p|%p: boot info structure\n", &bootinfo, bootinfo_pa); printf(" %p|%p: kernel entry point\n", (void *) PA2KA(BOOT_OFFSET), (void *) BOOT_OFFSET); printf(" %p|%p: loader entry point\n", (void *) LOADER_ADDRESS, loader_address_pa); size_t i; for (i = 0; i < COMPONENTS; i++) printf(" %p|%p: %s image (%zu/%zu bytes)\n", components[i].start, ofw_translate(components[i].start), components[i].name, components[i].inflated, components[i].size); size_t dest[COMPONENTS]; size_t top = 0; size_t cnt = 0; bootinfo.taskmap.cnt = 0; for (i = 0; i < min(COMPONENTS, TASKMAP_MAX_RECORDS); i++) { top = ALIGN_UP(top, PAGE_SIZE); if (i > 0) { bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].addr = (void *) PA2KA(top); bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].size = components[i].inflated; str_cpy(bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].name, BOOTINFO_TASK_NAME_BUFLEN, components[i].name); bootinfo.taskmap.cnt++; } dest[i] = top; top += components[i].inflated; cnt++; } void *balloc_base; void *balloc_base_pa; ofw_alloc("boot allocator area", &balloc_base, &balloc_base_pa, BALLOC_MAX_SIZE, loader_address_pa); printf(" %p|%p: boot allocator area\n", balloc_base, balloc_base_pa); void *inflate_base; void *inflate_base_pa; ofw_alloc("inflate area", &inflate_base, &inflate_base_pa, top, loader_address_pa); printf(" %p|%p: inflate area\n", inflate_base, inflate_base_pa); uintptr_t balloc_start = ALIGN_UP(top, PAGE_SIZE); size_t pages = (balloc_start + ALIGN_UP(BALLOC_MAX_SIZE, PAGE_SIZE)) >> PAGE_WIDTH; void *transtable; void *transtable_pa; ofw_alloc("translate table", &transtable, &transtable_pa, pages * sizeof(void *), loader_address_pa); printf(" %p|%p: translate table\n", transtable, transtable_pa); check_overlap("boot allocator area", balloc_base_pa, pages); check_overlap("inflate area", inflate_base_pa, pages); check_overlap("translate table", transtable_pa, pages); printf("\nInflating components ... "); for (i = cnt; i > 0; i--) { printf("%s ", components[i - 1].name); int err = inflate(components[i - 1].start, components[i - 1].size, inflate_base + dest[i - 1], components[i - 1].inflated); if (err != EOK) { printf("\n%s: Inflating error %d, halting.\n", components[i - 1].name, err); halt(); } } printf(".\n"); printf("Setting up boot allocator ...\n"); balloc_init(&bootinfo.ballocs, balloc_base, PA2KA(balloc_start), BALLOC_MAX_SIZE); printf("Setting up screens ...\n"); ofw_setup_screens(); printf("Canonizing OpenFirmware device tree ...\n"); bootinfo.ofw_root = ofw_tree_build(); printf("Setting up translate table ...\n"); for (i = 0; i < pages; i++) { uintptr_t off = i << PAGE_WIDTH; void *phys; if (off < balloc_start) phys = ofw_translate(inflate_base + off); else phys = ofw_translate(balloc_base + off - balloc_start); ((void **) transtable)[i] = phys; } printf("Booting the kernel...\n"); jump_to_kernel(bootinfo_pa, transtable_pa, pages, real_mode_pa); }
static ssize_t relocate_fvh(uintptr_t new_addr, void *fsp, size_t fsp_size, size_t fvh_offset, size_t *fih_offset) { EFI_FIRMWARE_VOLUME_HEADER *fvh; EFI_FFS_FILE_HEADER *ffsfh; EFI_COMMON_SECTION_HEADER *csh; size_t offset; size_t file_offset; size_t size; size_t fv_length; offset = fvh_offset; fvh = relative_offset(fsp, offset); if (read_le32(&fvh->Signature) != EFI_FVH_SIGNATURE) return -1; fv_length = read_le64(&fvh->FvLength); printk(FSP_DBG_LVL, "FVH length: %zx Offset: %zx Mapping length: %zx\n", fv_length, offset, fsp_size); if (fv_length + offset > fsp_size) return -1; /* Parse only this FV. However, the algorithm uses offsets into the * entire FSP region so make size include the starting offset. */ size = fv_length + offset; if (guid_compare(&fvh->FileSystemGuid, &ffs2_guid)) { printk(BIOS_ERR, "FVH not an FFS2 type.\n"); return -1; } if (read_le16(&fvh->ExtHeaderOffset) != 0) { EFI_FIRMWARE_VOLUME_EXT_HEADER *fveh; offset += read_le16(&fvh->ExtHeaderOffset); fveh = relative_offset(fsp, offset); printk(FSP_DBG_LVL, "Extended Header Offset: %zx Size: %zx\n", (size_t)read_le16(&fvh->ExtHeaderOffset), (size_t)read_le32(&fveh->ExtHeaderSize)); offset += read_le32(&fveh->ExtHeaderSize); /* FFS files are 8 byte aligned after extended header. */ offset = ALIGN_UP(offset, 8); } else { offset += read_le16(&fvh->HeaderLength); } file_offset = offset; while (file_offset + sizeof(*ffsfh) < size) { offset = file_offset; printk(FSP_DBG_LVL, "file offset: %zx\n", file_offset); /* First file and section should be FSP info header. */ if (fih_offset != NULL && *fih_offset == 0) *fih_offset = file_offset; ffsfh = relative_offset(fsp, file_offset); printk(FSP_DBG_LVL, "file type = %x\n", read_le8(&ffsfh->Type)); printk(FSP_DBG_LVL, "file attribs = %x\n", read_le8(&ffsfh->Attributes)); /* Exit FV relocation when empty space found */ if (read_le8(&ffsfh->Type) == EFI_FV_FILETYPE_FFS_MAX) break; /* Next file on 8 byte alignment. */ file_offset += ffs_file_size(ffsfh); file_offset = ALIGN_UP(file_offset, 8); /* Padding files have no section information. */ if (read_le8(&ffsfh->Type) == EFI_FV_FILETYPE_FFS_PAD) continue; offset += file_section_offset(ffsfh); while (offset + sizeof(*csh) < file_offset) { size_t data_size; size_t data_offset; csh = relative_offset(fsp, offset); printk(FSP_DBG_LVL, "section offset: %zx\n", offset); printk(FSP_DBG_LVL, "section type: %x\n", read_le8(&csh->Type)); data_size = section_data_size(csh); data_offset = section_data_offset(csh); if (data_size + data_offset + offset > file_offset) { printk(BIOS_ERR, "Section exceeds FV size.\n"); return -1; } /* * The entire FSP 1.1 image can be thought of as one * program with a single link address even though there * are multiple TEs linked separately. The reason is * that each TE is linked for XIP. So in order to * relocate the TE properly we need to form the * relocated address based on the TE offset within * FSP proper. */ if (read_le8(&csh->Type) == EFI_SECTION_TE) { void *te; size_t te_offset = offset + data_offset; uintptr_t te_addr = new_addr + te_offset; printk(FSP_DBG_LVL, "TE image at offset %zx\n", te_offset); te = relative_offset(fsp, te_offset); te_relocate(te_addr, te); } offset += data_size + data_offset; /* Sections are aligned to 4 bytes. */ offset = ALIGN_UP(offset, 4); } } /* Return amount of buffer parsed: FV size. */ return fv_length; }
static int __INIT__ flash_parse_part(struct flash_chip *host, struct part_attr *part, const char *part_def) { int i, ret = -EINVAL, index = 0; __u32 curr_base = 0; char buff[128]; const char *p; p = strchr(part_def, ':'); if (!p) goto error; p++; while (*p && *p != ';') { if (curr_base >= host->chip_size) goto error; while (' ' == *p) p++; // part size if (*p == '-') { part->size = host->chip_size - curr_base; p++; } else { for (i = 0; *p; i++, p++) { if (*p == '@' || *p == '(' || *p == 'r' || *p == ',') break; buff[i] = *p; } buff[i] = '\0'; ret = hr_str_to_val(buff, (unsigned long *)&part->size); if (ret < 0) goto error; ALIGN_UP(part->size, host->erase_size); } // part base if (*p == '@') { for (i = 0, p++; *p; i++, p++) { if (*p == '(' || *p == 'r' || *p == ',') break; buff[i] = *p; } buff[i] = '\0'; ret = hr_str_to_val(buff, (unsigned long *)&part->base); if (ret < 0) goto error; ALIGN_UP(part->base, host->erase_size); curr_base = part->base; } else { part->base = curr_base; } // part label and image i = 0; if (*p == '(') { for (p++; *p && *p != ')'; i++, p++) part->label[i] = *p; p++; } if (*p == 'r') { p++; if (*p != 'o') { return -EINVAL; } part->flags |= BDF_RDONLY; p++; } if (',' == *p) p++; part->label[i] = '\0'; curr_base += part->size; index++; part++; } return index; error: printf("%s(): invalid part definition \"%s\"\n", __func__, part_def); return ret; }
grub_err_t SUFFIX (grub_freebsd_load_elfmodule_obj) (grub_file_t file, int argc, char *argv[], grub_addr_t *kern_end) { Elf_Ehdr e; Elf_Shdr *s; char *shdr; grub_addr_t curload, module; grub_err_t err; err = read_headers (file, &e, &shdr); if (err) return err; curload = module = ALIGN_PAGE (*kern_end); for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr + e.e_shnum * e.e_shentsize); s = (Elf_Shdr *) ((char *) s + e.e_shentsize)) { if (s->sh_size == 0) continue; if (s->sh_addralign) curload = ALIGN_UP (curload, s->sh_addralign); s->sh_addr = curload; grub_dprintf ("bsd", "loading section to %x, size %d, align %d\n", (unsigned) curload, (int) s->sh_size, (int) s->sh_addralign); switch (s->sh_type) { default: case SHT_PROGBITS: err = load (file, UINT_TO_PTR (curload), s->sh_offset, s->sh_size); if (err) return err; break; case SHT_NOBITS: if (curload + s->sh_size > grub_os_area_addr + grub_os_area_size) return grub_error (GRUB_ERR_OUT_OF_RANGE, "not enough memory for the module"); grub_memset (UINT_TO_PTR (curload), 0, s->sh_size); break; } curload += s->sh_size; } *kern_end = ALIGN_PAGE (curload); err = grub_freebsd_add_meta_module (argv[0], FREEBSD_MODTYPE_ELF_MODULE_OBJ, argc - 1, argv + 1, module, curload - module); if (! err) err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_ELFHDR, &e, sizeof (e)); if (! err) err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_SHDR, shdr, e.e_shnum * e.e_shentsize); return err; }
static u32 alloc_mem(u32 bytes) { return alloc -= ALIGN_UP(bytes, 16); }
static grub_err_t grub_cbfs_find_file (struct grub_archelp_data *data, char **name, grub_int32_t *mtime, grub_uint32_t *mode) { grub_size_t offset; for (;; data->dofs = data->hofs + offset, data->next_hofs = ALIGN_UP (data->dofs + data->size, data->cbfs_align)) { struct cbfs_file hd; grub_size_t namesize; data->hofs = data->next_hofs; if (data->hofs >= data->cbfs_end) { *mode = GRUB_ARCHELP_ATTR_END; return GRUB_ERR_NONE; } if (grub_disk_read (data->disk, 0, data->hofs, sizeof (hd), &hd)) return grub_errno; if (grub_memcmp (hd.magic, CBFS_FILE_MAGIC, sizeof (hd.magic)) != 0) { *mode = GRUB_ARCHELP_ATTR_END; return GRUB_ERR_NONE; } data->size = grub_be_to_cpu32 (hd.len); (void) mtime; offset = grub_be_to_cpu32 (hd.offset); *mode = GRUB_ARCHELP_ATTR_FILE | GRUB_ARCHELP_ATTR_NOTIME; namesize = offset; if (namesize >= sizeof (hd)) namesize -= sizeof (hd); if (namesize == 0) continue; *name = grub_malloc (namesize + 1); if (*name == NULL) return grub_errno; if (grub_disk_read (data->disk, 0, data->hofs + sizeof (hd), namesize, *name)) { grub_free (*name); return grub_errno; } if ((*name)[0] == '\0') { grub_free (*name); *name = NULL; continue; } (*name)[namesize] = 0; data->dofs = data->hofs + offset; data->next_hofs = ALIGN_UP (data->dofs + data->size, data->cbfs_align); return GRUB_ERR_NONE; } }
static int load_of(uval64 rmo_start, uval64 rmo_size) { uval32 stub_addr = rmo_size - (1 << 20); char mem_node[64]; uval64 prop[2]; int ret; char *dum = NULL; retry: snprintf(mem_node, sizeof(mem_node), "/memory@0x%x", 0); prop[0] = 0; prop[1] = stub_addr; of_set_prop(mem_node, "available", prop, sizeof (prop)); char oftree[512]; char ofstub[512]; char ofdimg[512]; snprintf(oftree, sizeof(oftree), HYPE_ROOT "/%s/of_tree", oh_pname); snprintf(ofstub, sizeof(ofstub), HYPE_ROOT "/%s/of_image", oh_pname); snprintf(ofdimg, sizeof(ofdimg), HYPE_ROOT "/%s/of_tree.ofd", oh_pname); const char *const args[] = { "ofdfs", "pack", oftree, ofdimg, NULL }; run_command(args); uval32 stub_size; struct stat buf; ret = stat(ofstub, &buf); ASSERT(ret == 0, "Stat failure %s\n", ofstub); stub_size = buf.st_size + 4 * PGSIZE; uval32 data_size; ret = stat(ofdimg, &buf); ASSERT(ret == 0, "Stat failure %s\n", ofdimg); data_size = buf.st_size; uval32 bottom = ALIGN_DOWN(rmo_size - data_size - stub_size, 1 << 20); if (stub_addr > bottom) { stub_addr = bottom; goto retry; } uval32 data_addr = ALIGN_UP(stub_addr + stub_size, PGSIZE); int fd = open(ofstub, O_RDWR); ASSERT(fd >= 0, "bad fd for %s\n", ofstub); off_t offset = lseek(fd, 0x10, SEEK_SET); ASSERT(offset != ((off_t) - 1), "seek failure on %s\n", ofstub); write(fd, &data_addr, sizeof (data_addr)); close(fd); msg("Loading OF stub: 0x%x[0x%x]\n", stub_addr, stub_size); msg("Loading OF data: 0x%x[0x%x]\n", data_addr, data_size); laddr_load(ofstub, rmo_start + stub_addr, &dum); laddr_load(ofdimg, rmo_start + data_addr, &dum); set_file_printf("r5", "0x%lx", stub_addr); set_file_printf("r1", "0x%lx", stub_addr - PGSIZE); return 0; }
int main(int argc, char **argv) { char scratch[128]; hcall_fd = hcall_init(); int ret = parse_args(argc, argv); if (ret < 0) return ret; uval total = 0; ASSERT(num_ranges > 0, "No memory ranges specified\n"); ret = get_file("state", scratch, sizeof(scratch)); if (ret <= 0 || strncmp(scratch, "READY", ret) != 0) { bailout("Partition not ready\n"); } uval rmo_start = lranges[0].lr_base; uval rmo_size = lranges[0].lr_size; uval laddr = 0; uval img_base = 0; uval img_offset = 0; int count = 0; while (count < 255) { char image[256]; char image_laddr[256]; char data[64]; struct stat sbuf; uval base; snprintf(image, sizeof(image), HYPE_ROOT "/%s/image%02x", oh_pname, count); snprintf(image_laddr, sizeof(image_laddr), "image%02x_load", count); ++count; ret = stat(image, &sbuf); if (ret < 0) continue; ret = get_file(image_laddr, data, sizeof(data)); if (ret >= 0) { uval64 l = strtoull(data, NULL, 0); ASSERT(errno != ERANGE, "Corrupted data %s\n", image_laddr); laddr = l; } int size = laddr_load(image, rmo_start + laddr, &base); if (0 == img_base) { img_base = base; img_offset = laddr; } laddr = ALIGN_UP(laddr + size, PGSIZE); } char pinfo_buf[64]; uval64 pinfo; ret = get_file("pinfo", pinfo_buf, sizeof(pinfo_buf)); if (ret <= 0 || (pinfo = strtoull(pinfo_buf, NULL, 0)) <= 0) { pinfo = (uval64)-1; } uval lpid; hargs.opcode = H_CREATE_PARTITION; hargs.args[0] = rmo_start; hargs.args[1] = rmo_size; hargs.args[2] = pinfo; ret = hcall(&hargs); ASSERT(ret >= 0 && hargs.retval == 0, "hcall failure: %d " UVAL_CHOOSE("0x%x", "0x%lx") "\n", ret, hargs.retval); lpid = hargs.args[0]; set_file_printf("of_tree/ibm,partition-no", "0x%llx", lpid); set_file_printf("lpid", "0x%llx", lpid); set_file("state", "CREATED", -1); clean_vdevices(); of_add_memory(0, rmo_size); total += rmo_size; int i = 1; while (i < num_ranges) { uval64 base = lranges[i].lr_base; uval64 size = lranges[i].lr_size; add_memory(lpid, base, size); total += size; ++i; } #ifdef __PPC__ add_htab(lpid, total); #endif if (get_file_numeric("res_console_srv", &console_ua) < 0) { console_ua = 0; } else { vtys = 1; } uval64 vty0 = 0; if (vtys == 0 && console_ua == 0) { add_vty(0); } else { if (vtys > 0) { /* add vty and force it to be vty@0 */ vty0 = add_vterm(0, lpid); --vtys; } while (vtys > 0) { /* add vty and let it be the proper liobn */ add_vterm(-1, lpid); } } if (crq > 0) { ret = add_vdev(lpid, crq); if (ret == -1) { fprintf(stderr, "vdev failed : 0x%lx\n", crq); return 1; } } if (console_ua) { printf("Registering console vterm: " UVAL_CHOOSE("0x%lx","0x%llx")" -> 0x%lx:0x%llx\n", console_ua, lpid, vty0); hargs.opcode = H_REGISTER_VTERM; hargs.args[0] = console_ua; hargs.args[1] = lpid; hargs.args[2] = vty0; ret = hcall(&hargs); ASSERT(ret >= 0 && hargs.retval == 0, "hcall failure: %d " UVAL_CHOOSE("0x%x", "0x%lx") "\n", ret, hargs.retval); } add_llan(lpid); #ifdef __PPC__ load_of(lranges[0].lr_base, lranges[0].lr_size); #endif #ifdef __i386__ if (0 != img_base) { static struct partition_info part_info[2]; fill_pinfo(&part_info[1], lpid, rmo_size); if (inject_pinfo(part_info, sizeof(part_info), img_base, img_offset)) { add_cmdlineargs(img_base, 0x1000, /* offset in image for data */ lpid); } } #endif hargs.opcode = H_SET_SCHED_PARAMS; hargs.args[0] = lpid; hargs.args[1] = 0; hargs.args[2] = 1; hargs.args[3] = 0; ret = hcall(&hargs); ASSERT(ret >= 0 && hargs.retval == 0, "hcall failure: %d " UVAL_CHOOSE("0x%x", "0x%lx") "\n", ret, hargs.retval); hargs.opcode = H_START; hargs.args[0] = lpid; char buf[64]; ret = get_file("pc", buf, sizeof(buf)); if (ret >= 0) { buf[ret] = 0; hargs.args[1] = strtoull(buf, NULL, 0); } else { hargs.args[1] = 0; } int x = 2; while (x < 8) { int y = 0; snprintf(buf, sizeof(buf), "r%d", x); y = get_file(buf, buf, sizeof(buf)); if (y >= 0) { buf[y] = 0; hargs.args[x] = strtoull(buf, NULL, 0); } else { hargs.args[x] = 0; } ++x; } if (wait_for_key) { printf("waiting for keypress:"); (void)fgetc(stdin); } printf("Starting...\n"); hcall(&hargs); ASSERT(ret >= 0 && hargs.retval == 0, "hcall failure: %d " UVAL_CHOOSE("0x%x", "0x%lx") "\n", ret, hargs.retval); set_file("state", "RUNNING", -1); return 0; }
/* static */ SysStatusUval SysVSharedMem::MakeRegion(sval32 key, uval size, uval flags) { SysStatus rc = 0; uval addr; ObjectHandle frOH; RegionInfo *ri; uval perm; uval accMode; if (flags & SHM_HUGETLB) { rc = StubFRComputation::_CreateLargePage(frOH, LARGE_PAGES_SIZE); size = ALIGN_UP(size, LARGE_PAGES_SIZE); } else { rc = StubFRComputation::_Create(frOH); } if (_FAILURE(rc)) return rc; perm = (flags & (S_IRWXU|S_IRWXG|S_IRWXO)); if (!(perm & (S_IWUSR | S_IRUSR))) { tassertWrn(0,"Region perms are neither read or write.\n"); perm |= S_IWUSR; } // FIXME: this is wrong if (perm & S_IWUSR) { accMode = AccessMode::writeUserWriteSup; } else { accMode = AccessMode::readUserReadSup; } // FIXME: The only reason to bind the region in the servers // address space is to "reserve" at least one region somewhere // since the shamt cannot fail due to absence of memory resources. /* * Note: We cannot assume that all processes have the reion mapped * at the same address, so keeping track of this by our address * value is stupid. */ rc = StubRegionDefault::_CreateFixedLenExt( addr, size, 0, frOH, 0, accMode, 0, RegionType::K42Region); if (_FAILURE(rc)) { Obj::ReleaseAccess(frOH); return rc; } ri = new RegionInfo; if (ri == NULL) { Obj::ReleaseAccess(frOH); rc = DREFGOBJ(TheProcessRef)->regionDestroy(addr); tassert(_SUCCESS(rc), err_printf("region destroy @ 0x%lx: failed.\n", addr)); return _SERROR(2520, 0, ENOMEM); } ri->frOH = frOH; ri->addr = addr; // FIXME: need some sort of reuse policy!! ri->shmID = FetchAndAddSynced(&(obj->shmID), 1); tassert(ri->shmID > 0, err_printf("Blew the max shmget(2) id values\n")); ri->shmInfo.shm_perm.__key = key; ri->shmInfo.shm_perm.uid = 0; // uid of owner ri->shmInfo.shm_perm.gid = 0; // gid of owner ri->shmInfo.shm_perm.cuid = 0; // uid of creator ri->shmInfo.shm_perm.cgid = 0; // gid of creator ri->shmInfo.shm_perm.mode = perm; // perms ri->shmInfo.shm_perm.__seq = ri->shmID; // FIXME: I THINK ri->shmInfo.shm_segsz = size; // size of segment (bytes) ri->shmInfo.shm_atime = 0; // last attach time ri->shmInfo.shm_dtime = 0; // last dettach time // Should be time now ri->shmInfo.shm_ctime = 2; // last change time by shmctl() ri->shmInfo.shm_cpid = 1; // pid of creator ri->shmInfo.shm_lpid = 1; // pid of last shm operation ri->shmInfo.shm_nattch = 0; // number of current attaches AutoLock<BLock> al(&obj->lock); if(key != IPC_PRIVATE) { obj->regionsByKey.add(key, ri); } obj->regionsByShmID.add(ri->shmID, ri); obj->regionsByAddr.add(addr, ri); return _SRETUVAL(ri->shmID); }
mspace create_contiguous_mspace_with_base(size_t starting_capacity, size_t max_capacity, int locked, void *base) { struct mspace_contig_state *cs; unsigned int pagesize; mstate m; init_mparams(); pagesize = PAGESIZE; assert(starting_capacity <= max_capacity); assert(((uintptr_t)base & (pagesize-1)) == 0); assert(((uintptr_t)max_capacity & (pagesize-1)) == 0); starting_capacity = (size_t)ALIGN_UP(starting_capacity, pagesize); /* Make the first page read/write. dlmalloc needs to use that page. */ if (mprotect(base, starting_capacity, PROT_READ | PROT_WRITE) < 0) { goto error; } /* Create the mspace, pointing to the memory given. */ m = create_mspace_with_base((char *)base + sizeof(*cs), starting_capacity, locked); if (m == (mspace)0) { goto error; } /* Make sure that m is in the same page as base. */ assert(((uintptr_t)m & (uintptr_t)~(pagesize-1)) == (uintptr_t)base); /* Use some space for the information that our MORECORE needs. */ cs = (struct mspace_contig_state *)base; /* Find out exactly how much of the memory the mspace * is using. */ cs->brk = m->seg.base + m->seg.size; cs->top = (char *)base + max_capacity; assert((char *)base <= cs->brk); assert(cs->brk <= cs->top); /* Prevent access to the memory we haven't handed out yet. */ if (cs->brk != cs->top) { /* mprotect() requires page-aligned arguments, but it's possible * for cs->brk not to be page-aligned at this point. */ char *prot_brk = (char *)ALIGN_UP(cs->brk, pagesize); if ((mprotect(base, prot_brk - (char *)base, PROT_READ | PROT_WRITE) < 0) || (mprotect(prot_brk, cs->top - prot_brk, PROT_NONE) < 0)) { goto error; } } cs->m = m; cs->magic = CONTIG_STATE_MAGIC; return (mspace)m; error: return (mspace)0; }
void *Pool_realloc(Pool *self, void *ptr, size_t newsize) #endif { size_t i; BlockHeader *p; BlockHeader *s; size_t new_alloc_block_size; if (self->init_flag != self) { DEBUGLOG(("Pool_realloc: pool is not initialized: %s(%d)\n", file, line)); assert(0); return 0; } if (!ptr) { #ifdef POOL_DEBUG return Pool_malloc_debug(self, newsize, file, line); #else return Pool_malloc(self, newsize); #endif } if (!newsize) { #ifdef POOL_DEBUG Pool_free_debug(self, ptr, file, line); #else Pool_free(self, ptr); #endif return 0; } #ifdef POOL_DEBUG p = (BlockHeader *) ((char *) ptr - (HEADER_SIZE + WALL_SIZE)); #else p = (BlockHeader *) ((char *) ptr - HEADER_SIZE); #endif if (p->magic != MAGIC_NO || !p->occupied) { DEBUGLOG(("Pool_realloc: NG pointer: %s(%d)\n", file, line)); assert(0); return 0; } #ifdef POOL_DEBUG new_alloc_block_size = ALIGN_UP(HEADER_SIZE + newsize + WALL_SIZE * 2); #else new_alloc_block_size = ALIGN_UP(HEADER_SIZE + newsize); #endif if (p->size >= new_alloc_block_size) { if (p->size >= 2 * new_alloc_block_size && new_alloc_block_size >= HEADER_SIZE + SPLIT_MIN) { /* 縮んだ分を空き領域として回収 */ s = (BlockHeader *) ((char *) p + new_alloc_block_size); s->occupied = 0; s->magic = MAGIC_NO; #ifndef POOL_SLIST s->prev = p; #endif if (p->next->occupied) { s->size = p->size - new_alloc_block_size; s->next = p->next; #ifndef POOL_SLIST p->next->prev = s; #endif } else { if (self->loop_p == p->next) { self->loop_p = p->next->next; } s->size = p->size - new_alloc_block_size + p->next->size; s->next = p->next->next; #ifndef POOL_SLIST p->next->next->prev = s; #endif } p->size = new_alloc_block_size; p->next = s; } #ifdef POOL_DEBUG p->alloc_size = newsize; for (i = 0; i < WALL_SIZE; i++) { ((char *) ptr)[newsize + i] = WALL_CHAR; } #endif return ptr; } /* 以下、拡張 */ if (p->next->occupied || p->size + p->next->size < new_alloc_block_size) { #ifdef POOL_DEBUG void *newptr = Pool_malloc_debug(self, newsize, file, line); #else void *newptr = Pool_malloc(self, newsize); #endif if (!newptr) { DEBUGLOG(("Pool_realloc: return NULL: %s(%d)\n", file, line)); return 0; } for (i = 0; #ifdef POOL_DEBUG i < p->alloc_size; #else i < p->size - HEADER_SIZE; #endif i++) { ((char *) newptr)[i] = ((char *) ptr)[i]; } #ifdef POOL_DEBUG Pool_free_debug(self, ptr, file, line); #else Pool_free(self, ptr); #endif return newptr; }
unsigned PackArmPe::processImports() // pass 1 { static const unsigned char kernel32dll[] = "COREDLL.dll"; static const char llgpa[] = "\x0\x0""LoadLibraryW\x0\x0" "GetProcAddressA\x0\x0\x0" "CacheSync"; //static const char exitp[] = "ExitProcess\x0\x0\x0"; unsigned dllnum = 0; import_desc *im = (import_desc*) (ibuf + IDADDR(PEDIR_IMPORT)); import_desc * const im_save = im; if (IDADDR(PEDIR_IMPORT)) { while (im->dllname) dllnum++, im++; im = im_save; } struct udll { const upx_byte *name; const upx_byte *shname; unsigned ordinal; unsigned iat; LE32 *lookupt; unsigned npos; unsigned original_position; bool isk32; static int __acc_cdecl_qsort compare(const void *p1, const void *p2) { const udll *u1 = * (const udll * const *) p1; const udll *u2 = * (const udll * const *) p2; if (u1->isk32) return -1; if (u2->isk32) return 1; if (!*u1->lookupt) return 1; if (!*u2->lookupt) return -1; int rc = strcasecmp(u1->name,u2->name); if (rc) return rc; if (u1->ordinal) return -1; if (u2->ordinal) return 1; if (!u1->shname) return 1; if (!u2->shname) return -1; return strlen(u1->shname) - strlen(u2->shname); } }; // +1 for dllnum=0 Array(struct udll, dlls, dllnum+1); Array(struct udll *, idlls, dllnum+1); soimport = 1024; // safety unsigned ic,k32o; for (ic = k32o = 0; dllnum && im->dllname; ic++, im++) { idlls[ic] = dlls + ic; dlls[ic].name = ibuf + im->dllname; dlls[ic].shname = NULL; dlls[ic].ordinal = 0; dlls[ic].iat = im->iat; dlls[ic].lookupt = (LE32*) (ibuf + (im->oft ? im->oft : im->iat)); dlls[ic].npos = 0; dlls[ic].original_position = ic; dlls[ic].isk32 = strcasecmp(kernel32dll,dlls[ic].name) == 0; soimport += strlen(dlls[ic].name) + 1 + 4; for (IPTR_I(LE32, tarr, dlls[ic].lookupt); *tarr; tarr += 1) { if (*tarr & 0x80000000) { importbyordinal = true; soimport += 2; // ordinal num: 2 bytes dlls[ic].ordinal = *tarr & 0xffff; //if (dlls[ic].isk32) // kernel32ordinal = true,k32o++; } else { IPTR_I(const upx_byte, n, ibuf + *tarr + 2); unsigned len = strlen(n); soimport += len + 1; if (dlls[ic].shname == NULL || len < strlen (dlls[ic].shname)) dlls[ic].shname = n; } soimport++; // separator } } oimport = new upx_byte[soimport]; memset(oimport,0,soimport); oimpdlls = new upx_byte[soimport]; memset(oimpdlls,0,soimport); qsort(idlls,dllnum,sizeof (udll*),udll::compare); unsigned dllnamelen = sizeof (kernel32dll); unsigned dllnum2 = 1; for (ic = 0; ic < dllnum; ic++) if (!idlls[ic]->isk32 && (ic == 0 || strcasecmp(idlls[ic - 1]->name,idlls[ic]->name))) { dllnum2++; dllnamelen += strlen(idlls[ic]->name) + 1; } //fprintf(stderr,"dllnum=%d dllnum2=%d soimport=%d\n",dllnum,dllnum2,soimport); // info("Processing imports: %d DLLs", dllnum); // create the new import table im = (import_desc*) oimpdlls; LE32 *ordinals = (LE32*) (oimpdlls + (dllnum2 + 1) * sizeof(import_desc)); LE32 *lookuptable = ordinals + 4;// + k32o + (isdll ? 0 : 1); upx_byte *dllnames = ((upx_byte*) lookuptable) + (dllnum2 - 1) * 8; upx_byte *importednames = dllnames + (dllnamelen &~ 1); unsigned k32namepos = ptr_diff(dllnames,oimpdlls); memcpy(importednames, llgpa, ALIGN_UP((unsigned) sizeof(llgpa), 2u)); strcpy(dllnames,kernel32dll); im->dllname = k32namepos; im->iat = ptr_diff(ordinals,oimpdlls); *ordinals++ = ptr_diff(importednames,oimpdlls); // LoadLibraryW *ordinals++ = ptr_diff(importednames,oimpdlls) + 14; // GetProcAddressA *ordinals++ = ptr_diff(importednames,oimpdlls) + 14 + 18; // CacheSync dllnames += sizeof(kernel32dll); importednames += sizeof(llgpa); im++; for (ic = 0; ic < dllnum; ic++) if (idlls[ic]->isk32) { idlls[ic]->npos = k32namepos; /* if (idlls[ic]->ordinal) for (LE32 *tarr = idlls[ic]->lookupt; *tarr; tarr++) if (*tarr & 0x80000000) *ordinals++ = *tarr; */ } else if (ic && strcasecmp(idlls[ic-1]->name,idlls[ic]->name) == 0) idlls[ic]->npos = idlls[ic-1]->npos; else { im->dllname = idlls[ic]->npos = ptr_diff(dllnames,oimpdlls); im->iat = ptr_diff(lookuptable,oimpdlls); strcpy(dllnames,idlls[ic]->name); dllnames += strlen(idlls[ic]->name)+1; if (idlls[ic]->ordinal) *lookuptable = idlls[ic]->ordinal + 0x80000000; else if (idlls[ic]->shname) { if (ptr_diff(importednames,oimpdlls) & 1) importednames--; *lookuptable = ptr_diff(importednames,oimpdlls); importednames += 2; strcpy(importednames,idlls[ic]->shname); importednames += strlen(idlls[ic]->shname) + 1; } lookuptable += 2; im++; } soimpdlls = ALIGN_UP(ptr_diff(importednames,oimpdlls),4); Interval names(ibuf),iats(ibuf),lookups(ibuf); // create the preprocessed data //ordinals -= k32o; upx_byte *ppi = oimport; // preprocessed imports for (ic = 0; ic < dllnum; ic++) { LE32 *tarr = idlls[ic]->lookupt; #if 0 && ENABLE_THIS_AND_UNCOMPRESSION_WILL_BREAK if (!*tarr) // no imports from this dll continue; #endif set_le32(ppi,idlls[ic]->npos); set_le32(ppi+4,idlls[ic]->iat - rvamin); ppi += 8; for (; *tarr; tarr++) if (*tarr & 0x80000000) { /*if (idlls[ic]->isk32) { *ppi++ = 0xfe; // signed + odd parity set_le32(ppi,ptr_diff(ordinals,oimpdlls)); ordinals++; ppi += 4; } else*/ { *ppi++ = 0xff; set_le16(ppi,*tarr & 0xffff); ppi += 2; } } else { *ppi++ = 1; unsigned len = strlen(ibuf + *tarr + 2) + 1; memcpy(ppi,ibuf + *tarr + 2,len); ppi += len; names.add(*tarr,len + 2 + 1); } ppi++; unsigned esize = ptr_diff((char *)tarr, (char *)idlls[ic]->lookupt); lookups.add(idlls[ic]->lookupt,esize); if (ptr_diff(ibuf + idlls[ic]->iat, (char *)idlls[ic]->lookupt)) { memcpy(ibuf + idlls[ic]->iat, idlls[ic]->lookupt, esize); iats.add(idlls[ic]->iat,esize); } names.add(idlls[ic]->name,strlen(idlls[ic]->name) + 1 + 1); } ppi += 4; assert(ppi < oimport+soimport); soimport = ptr_diff(ppi,oimport); if (soimport == 4) soimport = 0; //OutputFile::dump("x0.imp", oimport, soimport); //OutputFile::dump("x1.imp", oimpdlls, soimpdlls); unsigned ilen = 0; names.flatten(); if (names.ivnum > 1) { // The area occupied by the dll and imported names is not continuous // so to still support uncompression, I can't zero the iat area. // This decreases compression ratio, so FIXME somehow. infoWarning("can't remove unneeded imports"); ilen += sizeof(import_desc) * dllnum; #if defined(DEBUG) if (opt->verbose > 3) names.dump(); #endif // do some work for the unpacker im = im_save; for (ic = 0; ic < dllnum; ic++, im++) { memset(im,FILLVAL,sizeof(*im)); im->dllname = ptr_diff(dlls[idlls[ic]->original_position].name,ibuf); } } else { iats.add(im_save,sizeof(import_desc) * dllnum); // zero unneeded data iats.clear(); lookups.clear(); } names.clear(); iats.add(&names); iats.add(&lookups); iats.flatten(); for (ic = 0; ic < iats.ivnum; ic++) ilen += iats.ivarr[ic].len; info("Imports: original size: %u bytes, preprocessed size: %u bytes",ilen,soimport); return names.ivnum == 1 ? names.ivarr[0].start : 0; }
static void* reserve_code(struct jit* jit, lua_State* L, size_t sz) { struct page* page; size_t off = (jit->pagenum > 0) ? jit->pages[jit->pagenum-1]->off : 0; size_t size = (jit->pagenum > 0) ? jit->pages[jit->pagenum-1]->size : 0; if (off + sz >= size) { int i; uint8_t* pdata; cfunction func; /* need to create a new page */ jit->pages = (struct page**) realloc(jit->pages, (++jit->pagenum) * sizeof(jit->pages[0])); size = ALIGN_UP(sz + LINKTABLE_MAX_SIZE + sizeof(struct page), jit->align_page_size); page = (struct page*) AllocPage(size); jit->pages[jit->pagenum-1] = page; pdata = (uint8_t*) page; page->size = size; page->off = sizeof(struct page); lua_newtable(L); #define ADDFUNC(DLL, NAME) \ lua_pushliteral(L, #NAME); \ func = DLL ? (cfunction) GetProcAddressA(DLL, #NAME) : NULL; \ func = func ? func : (cfunction) &NAME; \ lua_pushcfunction(L, (lua_CFunction) func); \ lua_rawset(L, -3) ADDFUNC(NULL, check_double); ADDFUNC(NULL, check_float); ADDFUNC(NULL, check_uint64); ADDFUNC(NULL, check_int64); ADDFUNC(NULL, check_int32); ADDFUNC(NULL, check_uint32); ADDFUNC(NULL, check_uintptr); ADDFUNC(NULL, check_enum); ADDFUNC(NULL, check_typed_pointer); ADDFUNC(NULL, check_typed_cfunction); ADDFUNC(NULL, check_complex_double); ADDFUNC(NULL, check_complex_float); ADDFUNC(NULL, unpack_varargs_stack); ADDFUNC(NULL, unpack_varargs_stack_skip); ADDFUNC(NULL, unpack_varargs_reg); ADDFUNC(NULL, unpack_varargs_float); ADDFUNC(NULL, unpack_varargs_int); ADDFUNC(NULL, push_cdata); ADDFUNC(NULL, push_int); ADDFUNC(NULL, push_uint); ADDFUNC(NULL, push_float); ADDFUNC(jit->kernel32_dll, SetLastError); ADDFUNC(jit->kernel32_dll, GetLastError); ADDFUNC(jit->lua_dll, luaL_error); ADDFUNC(jit->lua_dll, lua_pushnumber); ADDFUNC(jit->lua_dll, lua_pushboolean); ADDFUNC(jit->lua_dll, lua_gettop); ADDFUNC(jit->lua_dll, lua_rawgeti); ADDFUNC(jit->lua_dll, lua_pushnil); ADDFUNC(jit->lua_dll, lua_callk); ADDFUNC(jit->lua_dll, lua_settop); lua_pushliteral(L, "lua_remove"); lua_pushcfunction(L, (lua_CFunction) lua_removef); lua_rawset(L, -3); #undef ADDFUNC for (i = 0; extnames[i] != NULL; i++) { if (strcmp(extnames[i], "FUNCTION") == 0) { shred(pdata + page->off, 0, JUMP_SIZE); jit->function_extern = i; } else { lua_getfield(L, -1, extnames[i]); func = (cfunction) lua_tocfunction(L, -1); if (func == NULL) { luaL_error(L, "internal error: missing link for %s", extnames[i]); } compile_extern_jump(jit, L, func, pdata + page->off); lua_pop(L, 1); } page->off += JUMP_SIZE; } page->freed = page->off; lua_pop(L, 1); } else { page = jit->pages[jit->pagenum-1]; EnableWrite(page, page->size); } return (uint8_t*) page + page->off; }
void PackArmPe::pack(OutputFile *fo) { // FIXME: we need to think about better support for --exact if (opt->exact) throwCantPackExact(); const unsigned objs = ih.objects; isection = new pe_section_t[objs]; fi->seek(pe_offset+sizeof(ih),SEEK_SET); fi->readx(isection,sizeof(pe_section_t)*objs); rvamin = isection[0].vaddr; infoHeader("[Processing %s, format %s, %d sections]", fn_basename(fi->getName()), getName(), objs); // check the PE header // FIXME: add more checks if (!opt->force && ( (ih.cpu != 0x1c0 && ih.cpu != 0x1c2) || (ih.opthdrsize != 0xe0) || ((ih.flags & EXECUTABLE) == 0) || (ih.subsystem != 9) || (ih.entry == 0 /*&& !isdll*/) || (ih.ddirsentries != 16) // || IDSIZE(PEDIR_EXCEPTION) // is this used on arm? // || IDSIZE(PEDIR_COPYRIGHT) )) throwCantPack("unexpected value in PE header (try --force)"); if (IDSIZE(PEDIR_SEC)) IDSIZE(PEDIR_SEC) = IDADDR(PEDIR_SEC) = 0; // throwCantPack("compressing certificate info is not supported"); if (IDSIZE(PEDIR_COMRT)) throwCantPack(".NET files (win32/net) are not yet supported"); if (isdll) opt->win32_pe.strip_relocs = false; else if (opt->win32_pe.strip_relocs < 0) opt->win32_pe.strip_relocs = (ih.imagebase >= 0x10000); if (opt->win32_pe.strip_relocs) { if (ih.imagebase < 0x10000) throwCantPack("--strip-relocs is not allowed when imagebase < 0x10000"); else ih.flags |= RELOCS_STRIPPED; } if (memcmp(isection[0].name,"UPX",3) == 0) throwAlreadyPackedByUPX(); if (!opt->force && IDSIZE(15)) throwCantPack("file is possibly packed/protected (try --force)"); if (ih.entry && ih.entry < rvamin) throwCantPack("run a virus scanner on this file!"); if (!opt->force && ih.subsystem == 1) throwCantPack("subsystem 'native' is not supported (try --force)"); if (ih.filealign < 0x200) throwCantPack("filealign < 0x200 is not yet supported"); handleStub(fi,fo,pe_offset); const unsigned usize = ih.imagesize; const unsigned xtrasize = UPX_MAX(ih.datasize, 65536u) + IDSIZE(PEDIR_IMPORT) + IDSIZE(PEDIR_BOUNDIM) + IDSIZE(PEDIR_IAT) + IDSIZE(PEDIR_DELAYIMP) + IDSIZE(PEDIR_RELOC); ibuf.alloc(usize + xtrasize); // BOUND IMPORT support. FIXME: is this ok? fi->seek(0,SEEK_SET); fi->readx(ibuf,isection[0].rawdataptr); Interval holes(ibuf); unsigned ic,jc,overlaystart = 0; ibuf.clear(0, usize); for (ic = jc = 0; ic < objs; ic++) { if (isection[ic].rawdataptr && overlaystart < isection[ic].rawdataptr + isection[ic].size) overlaystart = ALIGN_UP(isection[ic].rawdataptr + isection[ic].size,ih.filealign); if (isection[ic].vsize == 0) isection[ic].vsize = isection[ic].size; if ((isection[ic].flags & PEFL_BSS) || isection[ic].rawdataptr == 0 || (isection[ic].flags & PEFL_INFO)) { holes.add(isection[ic].vaddr,isection[ic].vsize); continue; } if (isection[ic].vaddr + isection[ic].size > usize) throwCantPack("section size problem"); if (((isection[ic].flags & (PEFL_WRITE|PEFL_SHARED)) == (PEFL_WRITE|PEFL_SHARED))) if (!opt->force) throwCantPack("writable shared sections not supported (try --force)"); if (jc && isection[ic].rawdataptr - jc > ih.filealign) throwCantPack("superfluous data between sections"); fi->seek(isection[ic].rawdataptr,SEEK_SET); jc = isection[ic].size; if (jc > isection[ic].vsize) jc = isection[ic].vsize; if (isection[ic].vsize == 0) // hack for some tricky programs - may this break other progs? jc = isection[ic].vsize = isection[ic].size; if (isection[ic].vaddr + jc > ibuf.getSize()) throwInternalError("buffer too small 1"); fi->readx(ibuf + isection[ic].vaddr,jc); jc += isection[ic].rawdataptr; } // check for NeoLite if (find(ibuf + ih.entry, 64+7, "NeoLite", 7) >= 0) throwCantPack("file is already compressed with another packer"); unsigned overlay = file_size - stripDebug(overlaystart); if (overlay >= (unsigned) file_size) { #if 0 if (overlay < file_size + ih.filealign) overlay = 0; else if (!opt->force) throwNotCompressible("overlay problem (try --force)"); #endif overlay = 0; } checkOverlay(overlay); Resource res; Interval tlsiv(ibuf); Export xport((char*)(unsigned char*)ibuf); const unsigned dllstrings = processImports(); processTls(&tlsiv); // call before processRelocs!! processResources(&res); processExports(&xport); processRelocs(); //OutputFile::dump("x1", ibuf, usize); // some checks for broken linkers - disable filter if necessary bool allow_filter = true; if (ih.codebase == ih.database || ih.codebase + ih.codesize > ih.imagesize || (isection[virta2objnum(ih.codebase,isection,objs)].flags & PEFL_CODE) == 0) allow_filter = false; const unsigned oam1 = ih.objectalign - 1; // FIXME: disabled: the uncompressor would not allocate enough memory //objs = tryremove(IDADDR(PEDIR_RELOC),objs); // FIXME: if the last object has a bss then this won't work // newvsize = (isection[objs-1].vaddr + isection[objs-1].size + oam1) &~ oam1; // temporary solution: unsigned newvsize = (isection[objs-1].vaddr + isection[objs-1].vsize + oam1) &~ oam1; //fprintf(stderr,"newvsize=%x objs=%d\n",newvsize,objs); if (newvsize + soimport + sorelocs > ibuf.getSize()) throwInternalError("buffer too small 2"); memcpy(ibuf+newvsize,oimport,soimport); memcpy(ibuf+newvsize+soimport,orelocs,sorelocs); cimports = newvsize - rvamin; // rva of preprocessed imports crelocs = cimports + soimport; // rva of preprocessed fixups ph.u_len = newvsize + soimport + sorelocs; // some extra data for uncompression support unsigned s = 0; upx_byte * const p1 = ibuf + ph.u_len; memcpy(p1 + s,&ih,sizeof (ih)); s += sizeof (ih); memcpy(p1 + s,isection,ih.objects * sizeof(*isection)); s += ih.objects * sizeof(*isection); if (soimport) { set_le32(p1 + s,cimports); set_le32(p1 + s + 4,dllstrings); s += 8; } if (sorelocs) { set_le32(p1 + s,crelocs); p1[s + 4] = (unsigned char) (big_relocs & 6); s += 5; } if (soresources) { set_le16(p1 + s,icondir_count); s += 2; } // end of extra data set_le32(p1 + s,ptr_diff(p1,ibuf) - rvamin); s += 4; ph.u_len += s; obuf.allocForCompression(ph.u_len); // prepare packheader ph.u_len -= rvamin; // prepare filter Filter ft(ph.level); ft.buf_len = ih.codesize; ft.addvalue = ih.codebase - rvamin; // compress int filter_strategy = allow_filter ? 0 : -3; // disable filters for files with broken headers if (ih.codebase + ih.codesize > ph.u_len) { ft.buf_len = 1; filter_strategy = -3; } // limit stack size needed for runtime decompression upx_compress_config_t cconf; cconf.reset(); cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack compressWithFilters(&ft, 2048, &cconf, filter_strategy, ih.codebase, rvamin, 0, NULL, 0); // info: see buildLoader() newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) &~ oam1; /* if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) &~ oam1) > tlsindex + 4) tlsindex = 0; */ const unsigned lsize = getLoaderSize(); int identsize = 0; const unsigned codesize = getLoaderSection("IDENTSTR",&identsize); assert(identsize > 0); getLoaderSection("UPX1HEAD",(int*)&ic); identsize += ic; pe_section_t osection[4]; // section 0 : bss // 1 : [ident + header] + packed_data + unpacker + tls // 2 : not compressed data // 3 : resource data -- wince 5 needs a new section for this // identsplit - number of ident + (upx header) bytes to put into the PE header int identsplit = pe_offset + sizeof(osection) + sizeof(oh); if ((identsplit & 0x1ff) == 0) identsplit = 0; else if (((identsplit + identsize) ^ identsplit) < 0x200) identsplit = identsize; else identsplit = ALIGN_GAP(identsplit, 0x200); ic = identsize - identsplit; const unsigned c_len = ((ph.c_len + ic) & 15) == 0 ? ph.c_len : ph.c_len + 16 - ((ph.c_len + ic) & 15); obuf.clear(ph.c_len, c_len - ph.c_len); const unsigned s1size = ALIGN_UP(ic + c_len + codesize,4u) + sotls; const unsigned s1addr = (newvsize - (ic + c_len) + oam1) &~ oam1; const unsigned ncsection = (s1addr + s1size + oam1) &~ oam1; const unsigned upxsection = s1addr + ic + c_len; Reloc rel(1024); // new relocations are put here static const char* symbols_to_relocate[] = { "ONAM", "BIMP", "BREL", "FIBE", "FIBS", "ENTR", "DST0", "SRC0" }; for (unsigned s2r = 0; s2r < TABLESIZE(symbols_to_relocate); s2r++) { unsigned off = linker->getSymbolOffset(symbols_to_relocate[s2r]); if (off != 0xdeaddead) rel.add(off + upxsection, 3); } // new PE header memcpy(&oh,&ih,sizeof(oh)); oh.filealign = 0x200; // identsplit depends on this memset(osection,0,sizeof(osection)); oh.entry = upxsection; oh.objects = 4; oh.chksum = 0; // fill the data directory ODADDR(PEDIR_DEBUG) = 0; ODSIZE(PEDIR_DEBUG) = 0; ODADDR(PEDIR_IAT) = 0; ODSIZE(PEDIR_IAT) = 0; ODADDR(PEDIR_BOUNDIM) = 0; ODSIZE(PEDIR_BOUNDIM) = 0; // tls is put into section 1 ic = s1addr + s1size - sotls; super::processTls(&rel,&tlsiv,ic); ODADDR(PEDIR_TLS) = sotls ? ic : 0; ODSIZE(PEDIR_TLS) = sotls ? 0x18 : 0; ic += sotls; // these are put into section 2 ic = ncsection; // wince wants relocation data at the beginning of a section processRelocs(&rel); ODADDR(PEDIR_RELOC) = soxrelocs ? ic : 0; ODSIZE(PEDIR_RELOC) = soxrelocs; ic += soxrelocs; processImports(ic, linker->getSymbolOffset("IATT") + upxsection); ODADDR(PEDIR_IMPORT) = ic; ODSIZE(PEDIR_IMPORT) = soimpdlls; ic += soimpdlls; processExports(&xport,ic); ODADDR(PEDIR_EXPORT) = soexport ? ic : 0; ODSIZE(PEDIR_EXPORT) = soexport; if (!isdll && opt->win32_pe.compress_exports) { ODADDR(PEDIR_EXPORT) = IDADDR(PEDIR_EXPORT); ODSIZE(PEDIR_EXPORT) = IDSIZE(PEDIR_EXPORT); } ic += soexport; ic = (ic + oam1) &~ oam1; const unsigned res_start = ic; if (soresources) processResources(&res,ic); ODADDR(PEDIR_RESOURCE) = soresources ? ic : 0; ODSIZE(PEDIR_RESOURCE) = soresources; ic += soresources; const unsigned onam = ncsection + soxrelocs + ih.imagebase; linker->defineSymbol("start_of_dll_names", onam); linker->defineSymbol("start_of_imports", ih.imagebase + rvamin + cimports); linker->defineSymbol("start_of_relocs", crelocs + rvamin + ih.imagebase); linker->defineSymbol("filter_buffer_end", ih.imagebase + ih.codebase + ih.codesize); linker->defineSymbol("filter_buffer_start", ih.imagebase + ih.codebase); linker->defineSymbol("original_entry", ih.entry + ih.imagebase); linker->defineSymbol("uncompressed_length", ph.u_len); linker->defineSymbol("start_of_uncompressed", ih.imagebase + rvamin); linker->defineSymbol("compressed_length", ph.c_len); linker->defineSymbol("start_of_compressed", ih.imagebase + s1addr + identsize - identsplit); defineDecompressorSymbols(); relocateLoader(); MemBuffer loader(lsize); memcpy(loader, getLoader(), lsize); patchPackHeader(loader, lsize); // this is computed here, because soxrelocs changes some lines above const unsigned ncsize = soxrelocs + soimpdlls + soexport; const unsigned fam1 = oh.filealign - 1; // fill the sections strcpy(osection[0].name,"UPX0"); strcpy(osection[1].name,"UPX1"); strcpy(osection[2].name, "UPX2"); strcpy(osection[3].name, ".rsrc"); osection[0].vaddr = rvamin; osection[1].vaddr = s1addr; osection[2].vaddr = ncsection; osection[3].vaddr = res_start; osection[0].size = 0; osection[1].size = (s1size + fam1) &~ fam1; osection[2].size = (ncsize + fam1) &~ fam1; osection[3].size = (soresources + fam1) &~ fam1; osection[0].vsize = osection[1].vaddr - osection[0].vaddr; //osection[1].vsize = (osection[1].size + oam1) &~ oam1; //osection[2].vsize = (osection[2].size + oam1) &~ oam1; osection[1].vsize = osection[1].size; osection[2].vsize = osection[2].size; osection[3].vsize = osection[3].size; osection[0].rawdataptr = 0; osection[1].rawdataptr = (pe_offset + sizeof(oh) + sizeof(osection) + fam1) &~ fam1; osection[2].rawdataptr = osection[1].rawdataptr + osection[1].size; osection[3].rawdataptr = osection[2].rawdataptr + osection[2].size; osection[0].flags = (unsigned) (PEFL_BSS|PEFL_EXEC|PEFL_WRITE|PEFL_READ); osection[1].flags = (unsigned) (PEFL_DATA|PEFL_EXEC|PEFL_WRITE|PEFL_READ); osection[2].flags = (unsigned) (PEFL_DATA|PEFL_READ); osection[3].flags = (unsigned) (PEFL_DATA|PEFL_READ); oh.imagesize = (osection[3].vaddr + osection[3].vsize + oam1) &~ oam1; oh.bsssize = osection[0].vsize; oh.datasize = osection[2].vsize + osection[3].vsize; oh.database = osection[2].vaddr; oh.codesize = osection[1].vsize; oh.codebase = osection[1].vaddr; oh.headersize = osection[1].rawdataptr; if (rvamin < osection[0].rawdataptr) throwCantPack("object alignment too small"); if (opt->win32_pe.strip_relocs && !isdll) oh.flags |= RELOCS_STRIPPED; //for (ic = 0; ic < oh.filealign; ic += 4) // set_le32(ibuf + ic,get_le32("UPX ")); ibuf.clear(0, oh.filealign); info("Image size change: %u -> %u KiB", ih.imagesize / 1024, oh.imagesize / 1024); infoHeader("[Writing compressed file]"); if (soresources == 0) { oh.objects = 3; memset(&osection[3], 0, sizeof(osection[3])); } // write loader + compressed file fo->write(&oh,sizeof(oh)); fo->write(osection,sizeof(osection)); // some alignment if (identsplit == identsize) { unsigned n = osection[1].rawdataptr - fo->getBytesWritten() - identsize; assert(n <= oh.filealign); fo->write(ibuf, n); } fo->write(loader + codesize,identsize); infoWriting("loader", fo->getBytesWritten()); fo->write(obuf,c_len); infoWriting("compressed data", c_len); fo->write(loader,codesize); if (opt->debug.dump_stub_loader) OutputFile::dump(opt->debug.dump_stub_loader, loader, codesize); if ((ic = fo->getBytesWritten() & 3) != 0) fo->write(ibuf,4 - ic); fo->write(otls,sotls); if ((ic = fo->getBytesWritten() & fam1) != 0) fo->write(ibuf,oh.filealign - ic); fo->write(oxrelocs,soxrelocs); fo->write(oimpdlls,soimpdlls); fo->write(oexport,soexport); if ((ic = fo->getBytesWritten() & fam1) != 0) fo->write(ibuf,oh.filealign - ic); fo->write(oresources,soresources); if ((ic = fo->getBytesWritten() & fam1) != 0) fo->write(ibuf,oh.filealign - ic); #if 0 printf("%-13s: program hdr : %8ld bytes\n", getName(), (long) sizeof(oh)); printf("%-13s: sections : %8ld bytes\n", getName(), (long) sizeof(osection)); printf("%-13s: ident : %8ld bytes\n", getName(), (long) identsize); printf("%-13s: compressed : %8ld bytes\n", getName(), (long) c_len); printf("%-13s: decompressor : %8ld bytes\n", getName(), (long) codesize); printf("%-13s: tls : %8ld bytes\n", getName(), (long) sotls); printf("%-13s: resources : %8ld bytes\n", getName(), (long) soresources); printf("%-13s: imports : %8ld bytes\n", getName(), (long) soimpdlls); printf("%-13s: exports : %8ld bytes\n", getName(), (long) soexport); printf("%-13s: relocs : %8ld bytes\n", getName(), (long) soxrelocs); #endif // verify verifyOverlappingDecompression(); // copy the overlay copyOverlay(fo, overlay, &obuf); // finally check the compression ratio if (!checkFinalCompressionRatio(fo)) throwNotCompressible(); }
/* * Provide a variant that takes just the vtable for small fixed-size objects. * The aligned size is already computed and stored in vt->gc_descr. * Note: every SGEN_SCAN_START_SIZE or so we are given the chance to do some special * processing. We can keep track of where objects start, for example, * so when we scan the thread stacks for pinned objects, we can start * a search for the pinned object in SGEN_SCAN_START_SIZE chunks. */ GCObject* sgen_alloc_obj_nolock (GCVTable vtable, size_t size) { /* FIXME: handle OOM */ void **p; char *new_next; size_t real_size = size; TLAB_ACCESS_INIT; CANARIFY_SIZE(size); HEAVY_STAT (++stat_objects_alloced); if (real_size <= SGEN_MAX_SMALL_OBJ_SIZE) HEAVY_STAT (stat_bytes_alloced += size); else HEAVY_STAT (stat_bytes_alloced_los += size); size = ALIGN_UP (size); SGEN_ASSERT (6, sgen_vtable_get_descriptor (vtable), "VTable without descriptor"); if (G_UNLIKELY (has_per_allocation_action)) { static int alloc_count; int current_alloc = InterlockedIncrement (&alloc_count); if (collect_before_allocs) { if (((current_alloc % collect_before_allocs) == 0) && nursery_section) { sgen_perform_collection (0, GENERATION_NURSERY, "collect-before-alloc-triggered", TRUE); if (!degraded_mode && sgen_can_alloc_size (size) && real_size <= SGEN_MAX_SMALL_OBJ_SIZE) { // FIXME: g_assert_not_reached (); } } } else if (verify_before_allocs) { if ((current_alloc % verify_before_allocs) == 0) sgen_check_whole_heap_stw (); } } /* * We must already have the lock here instead of after the * fast path because we might be interrupted in the fast path * (after confirming that new_next < TLAB_TEMP_END) by the GC, * and we'll end up allocating an object in a fragment which * no longer belongs to us. * * The managed allocator does not do this, but it's treated * specially by the world-stopping code. */ if (real_size > SGEN_MAX_SMALL_OBJ_SIZE) { p = (void **)sgen_los_alloc_large_inner (vtable, ALIGN_UP (real_size)); } else { /* tlab_next and tlab_temp_end are TLS vars so accessing them might be expensive */ p = (void**)TLAB_NEXT; /* FIXME: handle overflow */ new_next = (char*)p + size; TLAB_NEXT = new_next; if (G_LIKELY (new_next < TLAB_TEMP_END)) { /* Fast path */ /* * FIXME: We might need a memory barrier here so the change to tlab_next is * visible before the vtable store. */ CANARIFY_ALLOC(p,real_size); SGEN_LOG (6, "Allocated object %p, vtable: %p (%s), size: %zd", p, vtable, sgen_client_vtable_get_name (vtable), size); binary_protocol_alloc (p , vtable, size, sgen_client_get_provenance ()); g_assert (*p == NULL); mono_atomic_store_seq (p, vtable); return (GCObject*)p; } /* Slow path */ /* there are two cases: the object is too big or we run out of space in the TLAB */ /* we also reach here when the thread does its first allocation after a minor * collection, since the tlab_ variables are initialized to NULL. * there can be another case (from ORP), if we cooperate with the runtime a bit: * objects that need finalizers can have the high bit set in their size * so the above check fails and we can readily add the object to the queue. * This avoids taking again the GC lock when registering, but this is moot when * doing thread-local allocation, so it may not be a good idea. */ if (TLAB_NEXT >= TLAB_REAL_END) { int available_in_tlab; /* * Run out of space in the TLAB. When this happens, some amount of space * remains in the TLAB, but not enough to satisfy the current allocation * request. Currently, we retire the TLAB in all cases, later we could * keep it if the remaining space is above a treshold, and satisfy the * allocation directly from the nursery. */ TLAB_NEXT -= size; /* when running in degraded mode, we continue allocing that way * for a while, to decrease the number of useless nursery collections. */ if (degraded_mode && degraded_mode < DEFAULT_NURSERY_SIZE) return alloc_degraded (vtable, size, FALSE); available_in_tlab = (int)(TLAB_REAL_END - TLAB_NEXT);//We'll never have tlabs > 2Gb if (size > tlab_size || available_in_tlab > SGEN_MAX_NURSERY_WASTE) { /* Allocate directly from the nursery */ p = (void **)sgen_nursery_alloc (size); if (!p) { /* * We couldn't allocate from the nursery, so we try * collecting. Even after the collection, we might * still not have enough memory to allocate the * object. The reason will most likely be that we've * run out of memory, but there is the theoretical * possibility that other threads might have consumed * the freed up memory ahead of us. * * What we do in this case is allocate degraded, i.e., * from the major heap. * * Ideally we'd like to detect the case of other * threads allocating ahead of us and loop (if we * always loop we will loop endlessly in the case of * OOM). */ sgen_ensure_free_space (real_size, GENERATION_NURSERY); if (!degraded_mode) p = (void **)sgen_nursery_alloc (size); } if (!p) return alloc_degraded (vtable, size, FALSE); zero_tlab_if_necessary (p, size); } else { size_t alloc_size = 0; if (TLAB_START) SGEN_LOG (3, "Retire TLAB: %p-%p [%ld]", TLAB_START, TLAB_REAL_END, (long)(TLAB_REAL_END - TLAB_NEXT - size)); sgen_nursery_retire_region (p, available_in_tlab); p = (void **)sgen_nursery_alloc_range (tlab_size, size, &alloc_size); if (!p) { /* See comment above in similar case. */ sgen_ensure_free_space (tlab_size, GENERATION_NURSERY); if (!degraded_mode) p = (void **)sgen_nursery_alloc_range (tlab_size, size, &alloc_size); } if (!p) return alloc_degraded (vtable, size, FALSE); /* Allocate a new TLAB from the current nursery fragment */ TLAB_START = (char*)p; TLAB_NEXT = TLAB_START; TLAB_REAL_END = TLAB_START + alloc_size; TLAB_TEMP_END = TLAB_START + MIN (SGEN_SCAN_START_SIZE, alloc_size); zero_tlab_if_necessary (TLAB_START, alloc_size); /* Allocate from the TLAB */ p = (void **)TLAB_NEXT; TLAB_NEXT += size; sgen_set_nursery_scan_start ((char*)p); } } else { /* Reached tlab_temp_end */ /* record the scan start so we can find pinned objects more easily */ sgen_set_nursery_scan_start ((char*)p); /* we just bump tlab_temp_end as well */ TLAB_TEMP_END = MIN (TLAB_REAL_END, TLAB_NEXT + SGEN_SCAN_START_SIZE); SGEN_LOG (5, "Expanding local alloc: %p-%p", TLAB_NEXT, TLAB_TEMP_END); } CANARIFY_ALLOC(p,real_size); } if (G_LIKELY (p)) { SGEN_LOG (6, "Allocated object %p, vtable: %p (%s), size: %zd", p, vtable, sgen_client_vtable_get_name (vtable), size); binary_protocol_alloc (p, vtable, size, sgen_client_get_provenance ()); mono_atomic_store_seq (p, vtable); } return (GCObject*)p; }
bool CMMALRenderer::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation) { ReleaseBuffers(); m_sourceWidth = width; m_sourceHeight = height; m_renderOrientation = orientation; m_fps = fps; m_iFlags = flags; m_format = format; CLog::Log(LOGDEBUG, "%s::%s - %dx%d->%dx%d@%.2f flags:%x format:%d ext:%x orient:%d", CLASSNAME, __func__, width, height, d_width, d_height, fps, flags, format, extended_format, orientation); m_RenderUpdateCallBackFn = NULL; m_RenderUpdateCallBackCtx = NULL; if ((m_format == RENDER_FMT_BYPASS) && g_application.GetCurrentPlayer()) { m_renderFeatures.clear(); m_scalingMethods.clear(); m_deinterlaceModes.clear(); m_deinterlaceMethods.clear(); if (m_RenderFeaturesCallBackFn) { (*m_RenderFeaturesCallBackFn)(m_RenderFeaturesCallBackCtx, m_renderFeatures); // after setting up m_renderFeatures, we are done with the callback m_RenderFeaturesCallBackFn = NULL; m_RenderFeaturesCallBackCtx = NULL; } g_application.m_pPlayer->GetRenderFeatures(m_renderFeatures); g_application.m_pPlayer->GetDeinterlaceMethods(m_deinterlaceMethods); g_application.m_pPlayer->GetDeinterlaceModes(m_deinterlaceModes); g_application.m_pPlayer->GetScalingMethods(m_scalingMethods); } // calculate the input frame aspect ratio CalculateFrameAspectRatio(d_width, d_height); ChooseBestResolution(fps); m_destWidth = g_graphicsContext.GetResInfo(m_resolution).iWidth; m_destHeight = g_graphicsContext.GetResInfo(m_resolution).iHeight; SetViewMode(CMediaSettings::Get().GetCurrentVideoSettings().m_ViewMode); ManageDisplay(); if (m_format == RENDER_FMT_MMAL|| m_format == RENDER_FMT_YUV420P) { MMAL_ES_FORMAT_T *es_format = mmal_format_alloc(); es_format->type = MMAL_ES_TYPE_VIDEO; es_format->es->video.crop.width = m_sourceWidth; es_format->es->video.crop.height = m_sourceHeight; if (m_format == RENDER_FMT_MMAL) { es_format->encoding = MMAL_ENCODING_OPAQUE; es_format->es->video.width = m_sourceWidth; es_format->es->video.height = m_sourceHeight; } else if (m_format == RENDER_FMT_YUV420P) { const int pitch = ALIGN_UP(m_sourceWidth, 32); const int aligned_height = ALIGN_UP(m_sourceHeight, 16); es_format->encoding = MMAL_ENCODING_I420; es_format->es->video.width = pitch; es_format->es->video.height = aligned_height; if (CONF_FLAGS_YUVCOEF_MASK(m_iFlags) == CONF_FLAGS_YUVCOEF_BT709) es_format->es->video.color_space = MMAL_COLOR_SPACE_ITUR_BT709; else if (CONF_FLAGS_YUVCOEF_MASK(m_iFlags) == CONF_FLAGS_YUVCOEF_BT601) es_format->es->video.color_space = MMAL_COLOR_SPACE_ITUR_BT601; else if (CONF_FLAGS_YUVCOEF_MASK(m_iFlags) == CONF_FLAGS_YUVCOEF_240M) es_format->es->video.color_space = MMAL_COLOR_SPACE_SMPTE240M; } if (m_bConfigured) UnInit(); m_bConfigured = init_vout(es_format); mmal_format_free(es_format); } else m_bConfigured = true; return m_bConfigured; }
GCObject* sgen_try_alloc_obj_nolock (GCVTable vtable, size_t size) { void **p; char *new_next; size_t real_size = size; TLAB_ACCESS_INIT; CANARIFY_SIZE(size); size = ALIGN_UP (size); SGEN_ASSERT (9, real_size >= SGEN_CLIENT_MINIMUM_OBJECT_SIZE, "Object too small"); SGEN_ASSERT (6, sgen_vtable_get_descriptor (vtable), "VTable without descriptor"); if (real_size > SGEN_MAX_SMALL_OBJ_SIZE) return NULL; if (G_UNLIKELY (size > tlab_size)) { /* Allocate directly from the nursery */ p = (void **)sgen_nursery_alloc (size); if (!p) return NULL; sgen_set_nursery_scan_start ((char*)p); /*FIXME we should use weak memory ops here. Should help specially on x86. */ zero_tlab_if_necessary (p, size); } else { int available_in_tlab; char *real_end; /* tlab_next and tlab_temp_end are TLS vars so accessing them might be expensive */ p = (void**)TLAB_NEXT; /* FIXME: handle overflow */ new_next = (char*)p + size; real_end = TLAB_REAL_END; available_in_tlab = (int)(real_end - (char*)p);//We'll never have tlabs > 2Gb if (G_LIKELY (new_next < real_end)) { TLAB_NEXT = new_next; /* Second case, we overflowed temp end */ if (G_UNLIKELY (new_next >= TLAB_TEMP_END)) { sgen_set_nursery_scan_start (new_next); /* we just bump tlab_temp_end as well */ TLAB_TEMP_END = MIN (TLAB_REAL_END, TLAB_NEXT + SGEN_SCAN_START_SIZE); SGEN_LOG (5, "Expanding local alloc: %p-%p", TLAB_NEXT, TLAB_TEMP_END); } } else if (available_in_tlab > SGEN_MAX_NURSERY_WASTE) { /* Allocate directly from the nursery */ p = (void **)sgen_nursery_alloc (size); if (!p) return NULL; zero_tlab_if_necessary (p, size); } else { size_t alloc_size = 0; sgen_nursery_retire_region (p, available_in_tlab); new_next = (char *)sgen_nursery_alloc_range (tlab_size, size, &alloc_size); p = (void**)new_next; if (!p) return NULL; TLAB_START = (char*)new_next; TLAB_NEXT = new_next + size; TLAB_REAL_END = new_next + alloc_size; TLAB_TEMP_END = new_next + MIN (SGEN_SCAN_START_SIZE, alloc_size); sgen_set_nursery_scan_start ((char*)p); zero_tlab_if_necessary (new_next, alloc_size); } } HEAVY_STAT (++stat_objects_alloced); HEAVY_STAT (stat_bytes_alloced += size); CANARIFY_ALLOC(p,real_size); SGEN_LOG (6, "Allocated object %p, vtable: %p (%s), size: %zd", p, vtable, sgen_client_vtable_get_name (vtable), size); binary_protocol_alloc (p, vtable, size, sgen_client_get_provenance ()); g_assert (*p == NULL); /* FIXME disable this in non debug builds */ mono_atomic_store_seq (p, vtable); return (GCObject*)p; }
grub_err_t SUFFIX (grub_freebsd_load_elf_meta) (grub_file_t file, grub_addr_t *kern_end) { grub_err_t err; Elf_Ehdr e; Elf_Shdr *s; char *shdr; unsigned symoff, stroff, symsize, strsize; grub_addr_t curload; grub_freebsd_addr_t symstart, symend, symentsize, dynamic; Elf_Sym *sym; const char *str; unsigned i; err = read_headers (file, &e, &shdr); if (err) return err; err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_ELFHDR, &e, sizeof (e)); if (err) return err; for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) (shdr + e.e_shnum * e.e_shentsize); s = (Elf_Shdr *) ((char *) s + e.e_shentsize)) if (s->sh_type == SHT_SYMTAB) break; if (s >= (Elf_Shdr *) ((char *) shdr + e.e_shnum * e.e_shentsize)) return grub_error (GRUB_ERR_BAD_OS, "no symbol table"); symoff = s->sh_offset; symsize = s->sh_size; symentsize = s->sh_entsize; s = (Elf_Shdr *) (shdr + e.e_shentsize * s->sh_link); stroff = s->sh_offset; strsize = s->sh_size; if (*kern_end + 4 * sizeof (grub_freebsd_addr_t) + symsize + strsize > grub_os_area_addr + grub_os_area_size) return grub_error (GRUB_ERR_OUT_OF_RANGE, "not enough memory for kernel symbols"); symstart = curload = ALIGN_UP (*kern_end, sizeof (grub_freebsd_addr_t)); *((grub_freebsd_addr_t *) UINT_TO_PTR (curload)) = symsize; curload += sizeof (grub_freebsd_addr_t); if (grub_file_seek (file, symoff) == (grub_off_t) -1) return grub_errno; sym = (Elf_Sym *) UINT_TO_PTR (curload); if (grub_file_read (file, UINT_TO_PTR (curload), symsize) != (grub_ssize_t) symsize) { if (! grub_errno) return grub_error (GRUB_ERR_BAD_OS, "invalid ELF"); return grub_errno; } curload += symsize; *((grub_freebsd_addr_t *) UINT_TO_PTR (curload)) = strsize; curload += sizeof (grub_freebsd_addr_t); if (grub_file_seek (file, stroff) == (grub_off_t) -1) return grub_errno; str = (char *) UINT_TO_PTR (curload); if (grub_file_read (file, UINT_TO_PTR (curload), strsize) != (grub_ssize_t) strsize) { if (! grub_errno) return grub_error (GRUB_ERR_BAD_OS, "invalid ELF"); return grub_errno; } curload += strsize; curload = ALIGN_UP (curload, sizeof (grub_freebsd_addr_t)); symend = curload; for (i = 0; i * symentsize < symsize; i++, sym = (Elf_Sym *) ((char *) sym + symentsize)) { const char *name = str + sym->st_name; if (grub_strcmp (name, "_DYNAMIC") == 0) break; } if (i * symentsize < symsize) { dynamic = sym->st_value; grub_dprintf ("bsd", "dynamic = %llx\n", (unsigned long long) dynamic); err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_DYNAMIC, &dynamic, sizeof (dynamic)); if (err) return err; } err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_SSYM, &symstart, sizeof (symstart)); if (err) return err; err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_ESYM, &symend, sizeof (symend)); if (err) return err; *kern_end = ALIGN_PAGE (curload); return GRUB_ERR_NONE; }
void rk_display_init(device_t dev, u32 lcdbase, unsigned long fb_size) { struct edid edid; uint32_t val; struct soc_rockchip_rk3288_config *conf = dev->chip_info; uint32_t lower = ALIGN_DOWN(lcdbase, MiB); uint32_t upper = ALIGN_UP(lcdbase + fb_size, MiB); enum vop_modes detected_mode = VOP_MODE_UNKNOWN; printk(BIOS_SPEW, "LCD framebuffer @%p\n", (void *)(lcdbase)); memset((void *)lcdbase, 0, fb_size); /* clear the framebuffer */ dcache_clean_invalidate_by_mva((void *)lower, upper - lower); mmu_config_range(lower / MiB, (upper - lower) / MiB, DCACHE_OFF); switch (conf->vop_mode) { case VOP_MODE_NONE: return; case VOP_MODE_AUTO_DETECT: /* try EDP first, then HDMI */ case VOP_MODE_EDP: printk(BIOS_DEBUG, "Attempting to setup EDP display.\n"); rkclk_configure_edp(); rkclk_configure_vop_aclk(conf->vop_id, 192 * MHz); /* grf_edp_ref_clk_sel: from internal 24MHz or 27MHz clock */ write32(&rk3288_grf->soc_con12, RK_SETBITS(1 << 4)); /* select epd signal from vop0 or vop1 */ val = (conf->vop_id == 1) ? RK_SETBITS(1 << 5) : RK_CLRBITS(1 << 5); write32(&rk3288_grf->soc_con6, val); rk_edp_init(); if (rk_edp_get_edid(&edid) == 0) { detected_mode = VOP_MODE_EDP; break; } else { printk(BIOS_WARNING, "Cannot get EDID from EDP.\n"); if (conf->vop_mode == VOP_MODE_EDP) return; } /* fall thru */ case VOP_MODE_HDMI: printk(BIOS_DEBUG, "Attempting to setup HDMI display.\n"); rkclk_configure_hdmi(); rkclk_configure_vop_aclk(conf->vop_id, 384 * MHz); rk_hdmi_init(conf->vop_id); if (rk_hdmi_get_edid(&edid) == 0) { detected_mode = VOP_MODE_HDMI; break; } else { printk(BIOS_WARNING, "Cannot get EDID from HDMI.\n"); if (conf->vop_mode == VOP_MODE_HDMI) return; } /* fall thru */ default: printk(BIOS_WARNING, "Cannot read any edid info, aborting.\n"); return; } if (rkclk_configure_vop_dclk(conf->vop_id, edid.mode.pixel_clock * KHz)) { printk(BIOS_WARNING, "config vop err\n"); return; } edid_set_framebuffer_bits_per_pixel(&edid, conf->framebuffer_bits_per_pixel, 0); rkvop_mode_set(conf->vop_id, &edid, detected_mode); rkvop_prepare(conf->vop_id, &edid); rkvop_enable(conf->vop_id, lcdbase); switch (detected_mode) { case VOP_MODE_HDMI: if (rk_hdmi_enable(&edid)) { printk(BIOS_WARNING, "hdmi enable err\n"); return; } /* * HACK: if we do remove this delay, HDMI TV may not show * anythings. So we make an delay here, ensure TV have * enough time to respond. */ mdelay(2000); break; case VOP_MODE_EDP: default: if (rk_edp_prepare()) { printk(BIOS_WARNING, "edp prepare err\n"); return; } if (rk_edp_enable()) { printk(BIOS_WARNING, "edp enable err\n"); return; } mainboard_power_on_backlight(); break; } set_vbe_mode_info_valid(&edid, (uintptr_t)lcdbase); }
static int scalecuda_resize(AVFilterContext *ctx, AVFrame *out, AVFrame *in) { AVHWFramesContext *in_frames_ctx = (AVHWFramesContext*)in->hw_frames_ctx->data; CUDAScaleContext *s = ctx->priv; switch (in_frames_ctx->sw_format) { case AV_PIX_FMT_YUV420P: call_resize_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1, in->data[0], in->width, in->height, in->linesize[0], out->data[0], out->width, out->height, out->linesize[0], 1); call_resize_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1, in->data[0]+in->linesize[0]*in->height, in->width/2, in->height/2, in->linesize[0]/2, out->data[0]+out->linesize[0]*out->height, out->width/2, out->height/2, out->linesize[0]/2, 1); call_resize_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1, in->data[0]+ ALIGN_UP((in->linesize[0]*in->height*5)/4, s->tex_alignment), in->width/2, in->height/2, in->linesize[0]/2, out->data[0]+(out->linesize[0]*out->height*5)/4, out->width/2, out->height/2, out->linesize[0]/2, 1); break; case AV_PIX_FMT_YUV444P: call_resize_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1, in->data[0], in->width, in->height, in->linesize[0], out->data[0], out->width, out->height, out->linesize[0], 1); call_resize_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1, in->data[0]+in->linesize[0]*in->height, in->width, in->height, in->linesize[0], out->data[0]+out->linesize[0]*out->height, out->width, out->height, out->linesize[0], 1); call_resize_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1, in->data[0]+in->linesize[0]*in->height*2, in->width, in->height, in->linesize[0], out->data[0]+out->linesize[0]*out->height*2, out->width, out->height, out->linesize[0], 1); break; case AV_PIX_FMT_NV12: call_resize_kernel(s, s->cu_func_uchar, s->cu_tex_uchar, 1, in->data[0], in->width, in->height, in->linesize[0], out->data[0], out->width, out->height, out->linesize[0], 1); call_resize_kernel(s, s->cu_func_uchar2, s->cu_tex_uchar2, 2, in->data[1], in->width/2, in->height/2, in->linesize[1], out->data[0] + out->linesize[0] * ((out->height + 31) & ~0x1f), out->width/2, out->height/2, out->linesize[1]/2, 1); break; case AV_PIX_FMT_P010LE: call_resize_kernel(s, s->cu_func_ushort, s->cu_tex_ushort, 1, in->data[0], in->width, in->height, in->linesize[0]/2, out->data[0], out->width, out->height, out->linesize[0]/2, 2); call_resize_kernel(s, s->cu_func_ushort2, s->cu_tex_ushort2, 2, in->data[1], in->width / 2, in->height / 2, in->linesize[1]/2, out->data[0] + out->linesize[0] * ((out->height + 31) & ~0x1f), out->width / 2, out->height / 2, out->linesize[1] / 4, 2); break; case AV_PIX_FMT_P016LE: call_resize_kernel(s, s->cu_func_ushort, s->cu_tex_ushort, 1, in->data[0], in->width, in->height, in->linesize[0] / 2, out->data[0], out->width, out->height, out->linesize[0] / 2, 2); call_resize_kernel(s, s->cu_func_ushort2, s->cu_tex_ushort2, 2, in->data[1], in->width / 2, in->height / 2, in->linesize[1] / 2, out->data[0] + out->linesize[0] * ((out->height + 31) & ~0x1f), out->width / 2, out->height / 2, out->linesize[1] / 4, 2); break; default: return AVERROR_BUG; } return 0; }
/************************************************* * HOST DRIVERS *************************************************/ void hostGPUDRV(CUfunction drvfun, int N, int nrhs, hostdrv_pars_t *prhs) { unsigned int maxthreads = MAXTHREADS_STREAM; int nstreams = iDivUp(N, maxthreads*BLOCK_DIM1D); CUresult err = CUDA_SUCCESS; for (int str = 0; str < nstreams; str++) { int offset = str * maxthreads * BLOCK_DIM1D; int size = 0; if (str == (nstreams - 1)) size = N - str * maxthreads * BLOCK_DIM1D; else size = maxthreads * BLOCK_DIM1D; int gridx = iDivUp(size, BLOCK_DIM1D); // number of x blocks // setup execution parameters if (CUDA_SUCCESS != (err = cuFuncSetBlockShape(drvfun, BLOCK_DIM1D, 1, 1))) { mexErrMsgTxt("Error in cuFuncSetBlockShape"); } if (CUDA_SUCCESS != cuFuncSetSharedSize(drvfun, 0)) { mexErrMsgTxt("Error in cuFuncSetSharedSize"); } // add parameters int poffset = 0; // CUDA kernels interface // N: number of elements // offset: used for streams ALIGN_UP(poffset, __alignof(size)); if (CUDA_SUCCESS != cuParamSeti(drvfun, poffset, size)) { mexErrMsgTxt("Error in cuParamSeti"); } poffset += sizeof(size); ALIGN_UP(poffset, __alignof(offset)); if (CUDA_SUCCESS != cuParamSeti(drvfun, poffset, offset)) { mexErrMsgTxt("Error in cuParamSeti"); } poffset += sizeof(offset); for (int p=0;p<nrhs;p++) { ALIGN_UP(poffset, prhs[p].align); if (CUDA_SUCCESS != cuParamSetv(drvfun, poffset, prhs[p].par, prhs[p].psize)) { mexErrMsgTxt("Error in cuParamSetv"); } poffset += prhs[p].psize; } if (CUDA_SUCCESS != cuParamSetSize(drvfun, poffset)) { mexErrMsgTxt("Error in cuParamSetSize"); } err = cuLaunchGridAsync(drvfun, gridx, 1, 0); if (CUDA_SUCCESS != err) { mexErrMsgTxt("Error running kernel"); } } }
internal_function new_heap (size_t size, size_t top_pad) { size_t pagesize = GLRO (dl_pagesize); char *p1, *p2; unsigned long ul; heap_info *h; if (size + top_pad < HEAP_MIN_SIZE) size = HEAP_MIN_SIZE; else if (size + top_pad <= HEAP_MAX_SIZE) size += top_pad; else if (size > HEAP_MAX_SIZE) return 0; else size = HEAP_MAX_SIZE; size = ALIGN_UP (size, pagesize); /* A memory region aligned to a multiple of HEAP_MAX_SIZE is needed. No swap space needs to be reserved for the following large mapping (on Linux, this is the case for all non-writable mappings anyway). */ p2 = MAP_FAILED; if (aligned_heap_area) { p2 = (char *) MMAP (aligned_heap_area, HEAP_MAX_SIZE, PROT_NONE, MAP_NORESERVE); aligned_heap_area = NULL; if (p2 != MAP_FAILED && ((unsigned long) p2 & (HEAP_MAX_SIZE - 1))) { __munmap (p2, HEAP_MAX_SIZE); p2 = MAP_FAILED; } } if (p2 == MAP_FAILED) { p1 = (char *) MMAP (0, HEAP_MAX_SIZE << 1, PROT_NONE, MAP_NORESERVE); if (p1 != MAP_FAILED) { p2 = (char *) (((unsigned long) p1 + (HEAP_MAX_SIZE - 1)) & ~(HEAP_MAX_SIZE - 1)); ul = p2 - p1; if (ul) __munmap (p1, ul); else aligned_heap_area = p2 + HEAP_MAX_SIZE; __munmap (p2 + HEAP_MAX_SIZE, HEAP_MAX_SIZE - ul); } else { /* Try to take the chance that an allocation of only HEAP_MAX_SIZE is already aligned. */ p2 = (char *) MMAP (0, HEAP_MAX_SIZE, PROT_NONE, MAP_NORESERVE); if (p2 == MAP_FAILED) return 0; if ((unsigned long) p2 & (HEAP_MAX_SIZE - 1)) { __munmap (p2, HEAP_MAX_SIZE); return 0; } } } if (__mprotect (p2, size, PROT_READ | PROT_WRITE) != 0) { __munmap (p2, HEAP_MAX_SIZE); return 0; } h = (heap_info *) p2; h->size = size; h->mprotect_size = size; LIBC_PROBE (memory_heap_new, 2, h, h->size); return h; }
int main(int argc, char *argv[]) { int quality = 75; if (argc == 2) { quality = atoi(argv[1]); if (quality < 10 || quality > 100) { fprintf(stderr, "invalid quality. must be between 10 and 100\n"); return 1; } } bcm_host_init(); uint32_t screen = 0; DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open(screen); DISPMANX_MODEINFO_T info; int ret = vc_dispmanx_display_get_info(display, &info); assert(ret == 0); /* DispmanX expects buffer rows to be aligned to a 32 bit boundary */ int pitch = ALIGN_UP(2 * info.width, 32); uint32_t vc_image_ptr; VC_IMAGE_TYPE_T type = VC_IMAGE_RGB565; DISPMANX_RESOURCE_HANDLE_T resource = vc_dispmanx_resource_create( type, info.width, info.height, &vc_image_ptr ); VC_IMAGE_TRANSFORM_T transform = 0; vc_dispmanx_snapshot(display, resource, transform); VC_RECT_T rect; vc_dispmanx_rect_set(&rect, 0, 0, info.width, info.height); unsigned char *image = malloc(pitch * info.height); assert(image); vc_dispmanx_resource_read_data(resource, &rect, image, info.width * 2); ret = vc_dispmanx_resource_delete(resource); assert(ret == 0); ret = vc_dispmanx_display_close(display); assert(ret == 0); struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; JSAMPROW row_pointer[1]; cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); jpeg_stdio_dest(&cinfo, stdout); cinfo.image_width = info.width; cinfo.image_height = info.height; cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, quality, TRUE); jpeg_start_compress(&cinfo, TRUE); int row_stride = cinfo.image_width * 3; while (cinfo.next_scanline < cinfo.image_height) { unsigned char row[row_stride]; unsigned char *dst = &row[0]; uint16_t *src = (uint16_t*)(image + pitch * cinfo.next_scanline); for (int x = 0; x < cinfo.image_width; x++, src++) { *dst++ = ((*src & 0xf800) >> 11) << 3; *dst++ = ((*src & 0x07e0) >> 5) << 2; *dst++ = ((*src & 0x001f) >> 0) << 3; } row_pointer[0] = row; jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); return 0; }
void PackBvmlinuzI386::buildLoader(const Filter *ft) { // prepare loader initLoader(stub_i386_linux_kernel_vmlinuz, sizeof(stub_i386_linux_kernel_vmlinuz)); if (0!=page_offset) { // relocatable kernel assert(0==ft->id || 0x40==(0xf0 & ft->id)); // others assume fixed buffer address addLoader("LINUZ000,LINUZ001,LINUZVGA,LINUZ101,LINUZ110", ((0!=config_physical_align) ? "LINUZ120" : "LINUZ130"), "LINUZ140,LZCUTPOI,LINUZ141", (ft->id ? "LINUZ145" : ""), (ph.first_offset_found == 1 ? "LINUZ010" : ""), NULL); } else { addLoader("LINUZ000,LINUZ001,LINUZVGA,LINUZ005", ph.first_offset_found == 1 ? "LINUZ010" : "", (0x40==(0xf0 & ft->id)) ? "LZCKLLT1" : (ft->id ? "LZCALLT1" : ""), "LBZIMAGE,IDENTSTR", "+40", // align the stuff to 4 byte boundary "UPX1HEAD", // 32 byte "LZCUTPOI", NULL); // fake alignment for the start of the decompressor //linker->defineSymbol("LZCUTPOI", 0x1000); } addLoader(getDecompressorSections(), NULL); if (ft->id) { assert(ft->calls > 0); if (0x40==(0xf0 & ft->id)) { addLoader("LZCKLLT9", NULL); } else { addLoader("LZCALLT9", NULL); } addFilter32(ft->id); } if (0!=page_offset) { addLoader("LINUZ150,IDENTSTR,+40,UPX1HEAD", NULL); unsigned const l_len = getLoaderSize(); unsigned const c_len = ALIGN_UP(ph.c_len, 4u); unsigned const e_len = getLoaderSectionStart("LINUZ141") - getLoaderSectionStart("LINUZ110"); linker->defineSymbol("compressed_length", c_len); linker->defineSymbol("load_physical_address", physical_start); // FIXME if (0!=config_physical_align) { linker->defineSymbol("neg_config_physical_align", 0u - config_physical_align); } linker->defineSymbol("neg_length_mov", 0u - ALIGN_UP(c_len + l_len, 4u)); linker->defineSymbol("neg_page_offset", 0u - page_offset); //linker->defineSymbol("physical_start", physical_start); linker->defineSymbol("unc_length", ph.u_len); linker->defineSymbol("dec_offset", ph.overlap_overhead + e_len); linker->defineSymbol("unc_offset", ph.overlap_overhead + ph.u_len - c_len); } else { addLoader("LINUZ990", NULL); } }
/* this is really aimed at the lcd panel. That said, there are two display * devices on this part and we may someday want to extend it for other boards. */ void display_startup(device_t dev) { struct soc_nvidia_tegra124_config *config = dev->chip_info; struct display_controller *disp_ctrl = (void *)config->display_controller; struct pwm_controller *pwm = (void *)TEGRA_PWM_BASE; struct tegra_dc *dc = &dc_data; u32 plld_rate; /* init dc */ dc->base = (void *)TEGRA_ARM_DISPLAYA; dc->config = config; config->dc_data = dc; /* Note dp_init may read EDID and change some config values. */ dp_init(config); /* should probably just make it all MiB ... in future */ u32 framebuffer_size_mb = config->framebuffer_size / MiB; u32 framebuffer_base_mb= config->framebuffer_base / MiB; /* light it all up */ /* This one may have been done in romstage but that's ok for now. */ if (config->panel_vdd_gpio){ gpio_output(config->panel_vdd_gpio, 1); printk(BIOS_SPEW,"%s: panel_vdd setting gpio %08x to %d\n", __func__, config->panel_vdd_gpio, 1); } udelay(config->vdd_delay_ms * 1000); if (config->backlight_vdd_gpio){ gpio_output(config->backlight_vdd_gpio, 1); printk(BIOS_SPEW,"%s: backlight vdd setting gpio %08x to %d\n", __func__, config->backlight_vdd_gpio, 1); } if (config->lvds_shutdown_gpio){ gpio_output(config->lvds_shutdown_gpio, 0); printk(BIOS_SPEW,"%s: lvds shutdown setting gpio %08x to %d\n", __func__, config->lvds_shutdown_gpio, 0); } if (framebuffer_size_mb == 0){ framebuffer_size_mb = ALIGN_UP(config->xres * config->yres * (config->framebuffer_bits_per_pixel / 8), MiB)/MiB; } if (! framebuffer_base_mb) framebuffer_base_mb = fb_base_mb(); config->framebuffer_size = framebuffer_size_mb * MiB; config->framebuffer_base = framebuffer_base_mb * MiB; mmu_config_range(framebuffer_base_mb, framebuffer_size_mb, DCACHE_WRITETHROUGH); printk(BIOS_SPEW, "LCD frame buffer at %dMiB to %dMiB\n", framebuffer_base_mb, framebuffer_base_mb + framebuffer_size_mb); /* GPIO magic here if needed to start powering up things. You * really only want to enable vdd, wait a bit, and then enable * the panel. However ... the timings in the tegra20 dts make * no sense to me. I'm pretty sure they're wrong. * The panel_vdd is done in the romstage, so we need only * light things up here once we're sure it's all working. */ /* The plld is programmed with the assumption of the SHIFT_CLK_DIVIDER * and PIXEL_CLK_DIVIDER are zero (divide by 1). See the * update_display_mode() for detail. */ plld_rate = clock_display(config->pixel_clock * 2); if (plld_rate == 0) { printk(BIOS_ERR, "dc: clock init failed\n"); return; } else if (plld_rate != config->pixel_clock * 2) { printk(BIOS_WARNING, "dc: plld rounded to %u\n", plld_rate); config->pixel_clock = plld_rate / 2; } /* Init dc */ if (tegra_dc_init(disp_ctrl)) { printk(BIOS_ERR, "dc: init failed\n"); return; } /* Configure dc mode */ if (update_display_mode(disp_ctrl, config)) { printk(BIOS_ERR, "dc: failed to configure display mode.\n"); return; } /* Enable dp */ dp_enable(dc->out); /* Init frame buffer */ memset((void *)(framebuffer_base_mb*MiB), 0x00, framebuffer_size_mb*MiB); update_window(disp_ctrl, config); /* Set up Tegra PWM n (where n is specified in config->pwm) to drive the * panel backlight. */ printk(BIOS_SPEW, "%s: enable panel backlight pwm\n", __func__); WRITEL(((1 << NV_PWM_CSR_ENABLE_SHIFT) | (220 << NV_PWM_CSR_PULSE_WIDTH_SHIFT) | /* 220/256 */ 0x02e), /* frequency divider */ &pwm->pwm[config->pwm].csr); udelay(config->pwm_to_bl_delay_ms * 1000); if (config->backlight_en_gpio){ gpio_output(config->backlight_en_gpio, 1); printk(BIOS_SPEW,"%s: backlight enable setting gpio %08x to %d\n", __func__, config->backlight_en_gpio, 1); } printk(BIOS_INFO, "%s: display init done.\n", __func__); /* tell depthcharge ... */ struct edid edid; edid.mode.va = config->yres; edid.mode.ha = config->xres; edid_set_framebuffer_bits_per_pixel(&edid, config->framebuffer_bits_per_pixel, 32); set_vbe_mode_info_valid(&edid, (uintptr_t)(framebuffer_base_mb*MiB)); }