diff options
author | Uwe Hermann <uwe@hermann-uwe.de> | 2008-11-02 17:01:06 +0000 |
---|---|---|
committer | Uwe Hermann <uwe@hermann-uwe.de> | 2008-11-02 17:01:06 +0000 |
commit | 7eb845e815924984b301aaf674b090cde28c1c6a (patch) | |
tree | d85a1080fd20b0ad8e1859d012fe90ba9cdf1cd9 /payloads/bayou/self.c | |
parent | 91df5619dbb7d2064f9947f2fbc56477f7b707c3 (diff) | |
download | coreboot-7eb845e815924984b301aaf674b090cde28c1c6a.tar.xz |
Import a slightly modified Bayou version into svn. This is based
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
Diffstat (limited to 'payloads/bayou/self.c')
-rw-r--r-- | payloads/bayou/self.c | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/payloads/bayou/self.c b/payloads/bayou/self.c new file mode 100644 index 0000000000..0de2a62260 --- /dev/null +++ b/payloads/bayou/self.c @@ -0,0 +1,147 @@ +/* + * 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; +} |