Example #1
0
void axfs_map_physmem(struct axfs_super *sbi, unsigned long size)
{
	void *addr;

	if (axfs_is_physmem(sbi)) {
		addr = AXFS_REMAP(sbi->phys_start_addr, size);
		sbi->virt_start_addr = (unsigned long)addr;
	}
}
Example #2
0
/******************************************************************************
 *
 * axfs_fetch_mmapable_data
 *
 * Description:
 *   Fetches pages of data.  Only called when a page is in the mmaped region.
 *
 * Parameters:
 *    (IN) sbi- axfs superblock pointer
 *
 *    (IN) fofffset - offset from the beginning of the filesystem
 *
 *    (IN) len - length to be fetched
 *
 * Returns:
 *    a vmalloc()'ed pointer with a copy of the requested data
 *
 *****************************************************************************/
static void *axfs_fetch_mmapable_data(struct axfs_super_incore *sbi, u64 fsoffset, u64 len) {
	unsigned long addr;
	void *copy_buffer;
	void *return_buffer;

	return_buffer = vmalloc((size_t)len);
	if(AXFS_PHYSADDR_IS_VALID(sbi)) {
		addr = sbi->phys_start_addr + (unsigned long)fsoffset;
		copy_buffer = AXFS_REMAP(addr, (unsigned long)len);
		memcpy(return_buffer, copy_buffer, (size_t)len);
		AXFS_UNMAP(copy_buffer);
	} else {
		addr = sbi->virt_start_addr + (unsigned long)fsoffset;
		memcpy(return_buffer, (void *)addr, (size_t)len);
	}

	return return_buffer;
}
Example #3
0
/******************************************************************************
 *
 * axfs_get_sb_physaddr
 *
 * Description:
 *      Populates a axfs_fill_super_info struct after sanity checking physaddr
 *
 * Parameters:
 *    (IN) physaddr - the physical address of to check
 *
 * Returns:
 *    pointer to a axfs_file_super_info or an error pointer
 *
 *****************************************************************************/
static struct axfs_fill_super_info * axfs_get_sb_physaddr(unsigned long physaddr)
{
	void *buffer;
	struct axfs_fill_super_info *output;
	int err = -EINVAL;

	if (physaddr == 0)
		goto out;

	if (physaddr & (PAGE_SIZE - 1)) {
		printk(KERN_ERR
		       "axfs: physical address 0x%lx for axfs image isn't aligned to a page boundary\n",
		       physaddr);
		goto out;
	}

	printk(KERN_INFO
	       "axfs: checking physical address 0x%lx for axfs image\n",
	       physaddr);

	buffer = AXFS_REMAP(physaddr, PAGE_SIZE);

	if(buffer == NULL) {
		printk(KERN_ERR "axfs: ioremap() failed at physical address 0x%lx\n", physaddr);
		goto out;
	}

	output = (struct axfs_fill_super_info *) vmalloc(sizeof(struct axfs_fill_super_info));
	output->onmedia_super_block = (struct axfs_super_onmedia *) vmalloc(sizeof(struct axfs_super_onmedia));
	memcpy((void *)output->onmedia_super_block, (void *)buffer, sizeof(struct axfs_super_onmedia));
	iounmap(buffer);

	output->physical_start_address = physaddr;
	output->virtual_start_address = 0;

	return output;

out:
	return ERR_PTR(err);
}
Example #4
0
/******************************************************************************
 *
 * axfs_do_fill_data_ptrs
 *
 * Description:
 *      Fills the incore region descriptor with data from the onmedia version.
 *    Processes the region to populate virt_addr by mapping to the physical
 *    address or copying the data to RAM or if the data can be fetched later,
 *    it is set to NULL.
 *
 * Parameters:
 *    (IN) sb - pointer to the super block on media
 *
 *    (IN) region_desc_offset - offset to the region descriptor from the
 *                                beginning of filesystem
 *
 *    (OUT) iregion - pointer to the in RAM copy of the region descriptor
 *
 *    (IN) force_va - if true the region must have a valid virt_addr
 *
 * Returns:
 *    0 or error number
 *
 *****************************************************************************/
static int axfs_do_fill_data_ptrs(struct super_block *sb, u64 region_desc_offset, struct axfs_region_desc_incore *iregion, int force_va) {
	struct axfs_super_incore *sbi;
	struct axfs_region_desc_onmedia *oregion;
	unsigned long addr;
	void *mapped = NULL;
	int err;
	u64 size;
	u64 end;
	u64 struct_len = sizeof(*oregion);

	sbi = AXFS_SB(sb);

	oregion = (struct axfs_region_desc_onmedia *) axfs_fetch_data(sb,region_desc_offset,struct_len);

	iregion->fsoffset = be64_to_cpu(oregion->fsoffset);
	iregion->size = be64_to_cpu(oregion->size);
	iregion->compressed_size = be64_to_cpu(oregion->compressed_size);
	iregion->max_index = be64_to_cpu(oregion->max_index);
	iregion->table_byte_depth = oregion->table_byte_depth;
	iregion->incore = oregion->incore;
	vfree(oregion);

    if (iregion->size == 0)
		return 0;

	end = iregion->fsoffset + iregion->size;
	if( (AXFS_IS_REGION_XIP(sbi,iregion)) && !(force_va && (sbi->mmap_size < end)) ) {
		if(AXFS_PHYSADDR_IS_VALID(sbi) ) {
			addr = sbi->phys_start_addr;
			addr += (unsigned long)iregion->fsoffset;
			size = (sbi->mmap_size > (iregion->fsoffset + iregion->size)) ? iregion->size : (sbi->mmap_size - iregion->fsoffset);
			iregion->virt_addr = AXFS_REMAP(addr,size);
		} else {
			addr = sbi->virt_start_addr;
			addr += (unsigned long)iregion->fsoffset;
			iregion->virt_addr = (void *)addr;
		}
	} else if(AXFS_IS_REGION_INCORE(iregion) || AXFS_IS_REGION_COMPRESSED(iregion) || force_va) {
		iregion->virt_addr = vmalloc(iregion->size);
		if(!(iregion->virt_addr)) {
			err = -ENOMEM;
			goto out;
		}
		if(AXFS_IS_REGION_COMPRESSED(iregion)) {
			mapped = axfs_fetch_data(sb,iregion->fsoffset,iregion->compressed_size);
			err = axfs_uncompress_block(iregion->virt_addr,iregion->size,mapped,iregion->compressed_size);
			if (err)
				goto out;
		} else {
			mapped = axfs_fetch_data(sb,iregion->fsoffset,iregion->size);
			memcpy(iregion->virt_addr,mapped,iregion->size);
		}
	} else {
		iregion->virt_addr = NULL;
	}

	if(mapped)
		vfree(mapped);
	return 0;

out:
	if(mapped)
		vfree(mapped);
	if(iregion->virt_addr)
		vfree(iregion->virt_addr);
	return err;
}