on the last snapshot posted by Jordan Crouse. This commit is long overdue. Changes by me include: - Rename 'utils' to 'util' for consistency with our other projects. - Move the main code out of src/* into the top-level directory. - Add missing license headers to the following files: Makefile, pbuilder/liblar/Makefile, util/pbuilder/Makefile. - Dropped the util/pbuilder/lzma completely. I'm working on reusing the lzma/ dir from v3 via svn:externals. Alas, this also means that Bayou won't yet compile out of the box. - Coding-style and white-space fixes (indent) for all files. Signed-off-by: Uwe Hermann <uwe@hermann-uwe.de> Acked-by: Uwe Hermann <uwe@hermann-uwe.de> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3719 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
		
			
				
	
	
		
			148 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			148 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * This file is part of the bayou project.
 | 
						|
 *
 | 
						|
 * Copyright (C) 2008 Advanced Micro Devices, Inc.
 | 
						|
 *
 | 
						|
 * This program is free software; you can redistribute it and/or modify
 | 
						|
 * it under the terms of the GNU General Public License version 2 as
 | 
						|
 * published by the Free Software Foundation.
 | 
						|
 *
 | 
						|
 * This program is distributed in the hope that it will be useful,
 | 
						|
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
 * GNU General Public License for more details.
 | 
						|
 *
 | 
						|
 * You should have received a copy of the GNU General Public License
 | 
						|
 * along with this program; if not, write to the Free Software
 | 
						|
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 | 
						|
 */
 | 
						|
 | 
						|
#include "bayou.h"
 | 
						|
#include "self.h"
 | 
						|
 | 
						|
static int nop_decompress(void *dst, void *src, int len)
 | 
						|
{
 | 
						|
	memcpy(dst, src, len);
 | 
						|
	return len;
 | 
						|
}
 | 
						|
 | 
						|
#ifdef CONFIG_LZMA
 | 
						|
extern int ulzma(u8 *, u8 *);
 | 
						|
 | 
						|
static int lzma_decompress(void *dst, void *src, int len)
 | 
						|
{
 | 
						|
	return ulzma((u8 *) src, (u8 *) dst);
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef CONFIG_NRV2B
 | 
						|
extern int unrv2b(u8 *, u8 *, unsigned long *);
 | 
						|
 | 
						|
static int nrv2b_decompress(void *dst, void *src, int len)
 | 
						|
{
 | 
						|
	unsigned long l = (u32) len;
 | 
						|
	return unrv2b(src, dst, &l);
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
static int zeros_decompress(void *dst, void *src, int len)
 | 
						|
{
 | 
						|
	memset(dst, 0, len);
 | 
						|
	return len;
 | 
						|
}
 | 
						|
 | 
						|
int self_get_params(u8 *fptr, u8 **params)
 | 
						|
{
 | 
						|
	struct self_segment *seg = (struct self_segment *)fptr;
 | 
						|
 | 
						|
	while (seg->type != SELF_TYPE_ENTRY) {
 | 
						|
		if (seg->type == 0)
 | 
						|
			return -1;
 | 
						|
 | 
						|
		if (seg->type == SELF_TYPE_PARAMS) {
 | 
						|
			*params = (u8 *) (fptr + seg->offset);
 | 
						|
			return seg->len;
 | 
						|
		}
 | 
						|
 | 
						|
		seg++;
 | 
						|
	}
 | 
						|
 | 
						|
	*params = NULL;
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
int verify_self(u8 *ptr)
 | 
						|
{
 | 
						|
	struct self_segment *seg = (struct self_segment *)ptr;
 | 
						|
 | 
						|
	switch (seg->type) {
 | 
						|
	case SELF_TYPE_CODE:
 | 
						|
	case SELF_TYPE_DATA:
 | 
						|
	case SELF_TYPE_BSS:
 | 
						|
	case SELF_TYPE_PARAMS:
 | 
						|
	case SELF_TYPE_ENTRY:
 | 
						|
		return 1;
 | 
						|
	}
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
int self_load_and_run(struct payload *p, int *ret)
 | 
						|
{
 | 
						|
	struct self_segment *seg = (struct self_segment *)p->fptr;
 | 
						|
	int (*dcmp) (void *, void *, int);
 | 
						|
	int dlen;
 | 
						|
 | 
						|
	switch (p->stat.compression) {
 | 
						|
#ifdef CONFIG_LZMA
 | 
						|
	case ALGO_LZMA:
 | 
						|
		dcmp = lzma_decompress;
 | 
						|
		break;
 | 
						|
#endif
 | 
						|
#ifdef CONFIG_NRV2B
 | 
						|
	case ALGO_NRV2B:
 | 
						|
		dcmp = nrv2b_decompress;
 | 
						|
		break;
 | 
						|
#endif
 | 
						|
	case ALGO_ZEROES:
 | 
						|
		dcmp = zeros_decompress;
 | 
						|
		break;
 | 
						|
	case ALGO_NONE:
 | 
						|
		dcmp = nop_decompress;
 | 
						|
	default:
 | 
						|
		printf("E: Unsupported decompression type\n");
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	while (1) {
 | 
						|
		u32 laddr = (u32) (seg->load_addr & 0xFFFFFFFF);
 | 
						|
 | 
						|
		switch (seg->type) {
 | 
						|
		case SELF_TYPE_CODE:
 | 
						|
		case SELF_TYPE_DATA:
 | 
						|
			dlen = dcmp((void *)laddr,
 | 
						|
				    (void *)p->fptr + seg->offset, seg->len);
 | 
						|
 | 
						|
			if (dlen < seg->mem_len) {
 | 
						|
				memset((void *)(laddr + dlen), 0,
 | 
						|
				       seg->mem_len - dlen);
 | 
						|
			}
 | 
						|
			break;
 | 
						|
 | 
						|
		case SELF_TYPE_BSS:
 | 
						|
			memset((void *)laddr, 0, seg->len);
 | 
						|
			break;
 | 
						|
		case SELF_TYPE_ENTRY:
 | 
						|
			*ret = exec(laddr, 0, NULL);
 | 
						|
			return 0;
 | 
						|
		default:
 | 
						|
			break;
 | 
						|
		}
 | 
						|
 | 
						|
		seg++;
 | 
						|
	}
 | 
						|
 | 
						|
	return -1;
 | 
						|
}
 |