2 * This file is part of the bayou project.
4 * Copyright (C) 2008 Advanced Micro Devices, Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 static int nop_decompress(void *dst, void *src, int len)
25 memcpy(dst, src, len);
30 extern int ulzma(u8 *, u8 *);
32 static int lzma_decompress(void *dst, void *src, int len)
34 return ulzma((u8 *) src, (u8 *) dst);
39 extern int unrv2b(u8 *, u8 *, unsigned long *);
41 static int nrv2b_decompress(void *dst, void *src, int len)
43 unsigned long l = (u32) len;
44 return unrv2b(src, dst, &l);
48 static int zeros_decompress(void *dst, void *src, int len)
54 int self_get_params(u8 *fptr, u8 **params)
56 struct self_segment *seg = (struct self_segment *)fptr;
58 while (seg->type != SELF_TYPE_ENTRY) {
62 if (seg->type == SELF_TYPE_PARAMS) {
63 *params = (u8 *) (fptr + seg->offset);
75 int verify_self(u8 *ptr)
77 struct self_segment *seg = (struct self_segment *)ptr;
83 case SELF_TYPE_PARAMS:
91 int self_load_and_run(struct payload *p, int *ret)
93 struct self_segment *seg = (struct self_segment *)p->fptr;
94 int (*dcmp) (void *, void *, int);
97 switch (p->stat.compression) {
100 dcmp = lzma_decompress;
105 dcmp = nrv2b_decompress;
109 dcmp = zeros_decompress;
112 dcmp = nop_decompress;
114 printf("E: Unsupported decompression type\n");
119 u32 laddr = (u32) (seg->load_addr & 0xFFFFFFFF);
124 dlen = dcmp((void *)laddr,
125 (void *)p->fptr + seg->offset, seg->len);
127 if (dlen < seg->mem_len) {
128 memset((void *)(laddr + dlen), 0,
129 seg->mem_len - dlen);
134 memset((void *)laddr, 0, seg->len);
136 case SELF_TYPE_ENTRY:
137 *ret = exec(laddr, 0, NULL);