tree: drop last paragraph of GPL copyright header
[coreboot.git] / payloads / bayou / self.c
blob88e495b17a07398558e7bf0dc3b2f540d4d64398
1 /*
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.
16 #include "bayou.h"
17 #include "self.h"
19 static int nop_decompress(void *dst, void *src, int len)
21 memcpy(dst, src, len);
22 return len;
25 #ifdef CONFIG_LZMA
26 extern int ulzma(u8 *, u8 *);
28 static int lzma_decompress(void *dst, void *src, int len)
30 return ulzma((u8 *) src, (u8 *) dst);
32 #endif
34 #ifdef CONFIG_NRV2B
35 extern int unrv2b(u8 *, u8 *, unsigned long *);
37 static int nrv2b_decompress(void *dst, void *src, int len)
39 unsigned long l = (u32) len;
40 return unrv2b(src, dst, &l);
42 #endif
44 static int zeros_decompress(void *dst, void *src, int len)
46 memset(dst, 0, len);
47 return len;
50 int self_get_params(u8 *fptr, u8 **params)
52 struct self_segment *seg = (struct self_segment *)fptr;
54 while (seg->type != SELF_TYPE_ENTRY) {
55 if (seg->type == 0)
56 return -1;
58 if (seg->type == SELF_TYPE_PARAMS) {
59 *params = (u8 *) (fptr + seg->offset);
60 return seg->len;
63 seg++;
66 *params = NULL;
68 return 0;
71 int verify_self(u8 *ptr)
73 struct self_segment *seg = (struct self_segment *)ptr;
75 switch (seg->type) {
76 case SELF_TYPE_CODE:
77 case SELF_TYPE_DATA:
78 case SELF_TYPE_BSS:
79 case SELF_TYPE_PARAMS:
80 case SELF_TYPE_ENTRY:
81 return 1;
84 return 0;
87 int self_load_and_run(struct payload *p, int *ret)
89 struct self_segment *seg = (struct self_segment *)p->fptr;
90 int (*dcmp) (void *, void *, int);
91 int dlen;
93 switch (p->stat.compression) {
94 #ifdef CONFIG_LZMA
95 case ALGO_LZMA:
96 dcmp = lzma_decompress;
97 break;
98 #endif
99 #ifdef CONFIG_NRV2B
100 case ALGO_NRV2B:
101 dcmp = nrv2b_decompress;
102 break;
103 #endif
104 case ALGO_ZEROES:
105 dcmp = zeros_decompress;
106 break;
107 case ALGO_NONE:
108 dcmp = nop_decompress;
109 default:
110 printf("E: Unsupported decompression type\n");
111 return -1;
114 while (1) {
115 u32 laddr = (u32) (seg->load_addr & 0xFFFFFFFF);
117 switch (seg->type) {
118 case SELF_TYPE_CODE:
119 case SELF_TYPE_DATA:
120 dlen = dcmp((void *)laddr,
121 (void *)p->fptr + seg->offset, seg->len);
123 if (dlen < seg->mem_len) {
124 memset((void *)(laddr + dlen), 0,
125 seg->mem_len - dlen);
127 break;
129 case SELF_TYPE_BSS:
130 memset((void *)laddr, 0, seg->len);
131 break;
132 case SELF_TYPE_ENTRY:
133 *ret = exec(laddr, 0, NULL);
134 return 0;
135 default:
136 break;
139 seg++;
142 return -1;