Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/boot/compressed/misc.c
10819 views
1
/*
2
* misc.c
3
*
4
* This is a collection of several routines from gzip-1.0.3
5
* adapted for Linux.
6
*
7
* malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
8
*
9
* Modified for ARM Linux by Russell King
10
*
11
* Nicolas Pitre <[email protected]> 1999/04/14 :
12
* For this code to run directly from Flash, all constant variables must
13
* be marked with 'const' and all other variables initialized at run-time
14
* only. This way all non constant variables will end up in the bss segment,
15
* which should point to addresses in RAM and cleared to 0 on start.
16
* This allows for a much quicker boot time.
17
*/
18
19
unsigned int __machine_arch_type;
20
21
#define _LINUX_STRING_H_
22
23
#include <linux/compiler.h> /* for inline */
24
#include <linux/types.h> /* for size_t */
25
#include <linux/stddef.h> /* for NULL */
26
#include <linux/linkage.h>
27
#include <asm/string.h>
28
29
30
static void putstr(const char *ptr);
31
extern void error(char *x);
32
33
#include <mach/uncompress.h>
34
35
#ifdef CONFIG_DEBUG_ICEDCC
36
37
#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
38
39
static void icedcc_putc(int ch)
40
{
41
int status, i = 0x4000000;
42
43
do {
44
if (--i < 0)
45
return;
46
47
asm volatile ("mrc p14, 0, %0, c0, c1, 0" : "=r" (status));
48
} while (status & (1 << 29));
49
50
asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch));
51
}
52
53
54
#elif defined(CONFIG_CPU_XSCALE)
55
56
static void icedcc_putc(int ch)
57
{
58
int status, i = 0x4000000;
59
60
do {
61
if (--i < 0)
62
return;
63
64
asm volatile ("mrc p14, 0, %0, c14, c0, 0" : "=r" (status));
65
} while (status & (1 << 28));
66
67
asm("mcr p14, 0, %0, c8, c0, 0" : : "r" (ch));
68
}
69
70
#else
71
72
static void icedcc_putc(int ch)
73
{
74
int status, i = 0x4000000;
75
76
do {
77
if (--i < 0)
78
return;
79
80
asm volatile ("mrc p14, 0, %0, c0, c0, 0" : "=r" (status));
81
} while (status & 2);
82
83
asm("mcr p14, 0, %0, c1, c0, 0" : : "r" (ch));
84
}
85
86
#endif
87
88
#define putc(ch) icedcc_putc(ch)
89
#endif
90
91
static void putstr(const char *ptr)
92
{
93
char c;
94
95
while ((c = *ptr++) != '\0') {
96
if (c == '\n')
97
putc('\r');
98
putc(c);
99
}
100
101
flush();
102
}
103
104
105
void *memcpy(void *__dest, __const void *__src, size_t __n)
106
{
107
int i = 0;
108
unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
109
110
for (i = __n >> 3; i > 0; i--) {
111
*d++ = *s++;
112
*d++ = *s++;
113
*d++ = *s++;
114
*d++ = *s++;
115
*d++ = *s++;
116
*d++ = *s++;
117
*d++ = *s++;
118
*d++ = *s++;
119
}
120
121
if (__n & 1 << 2) {
122
*d++ = *s++;
123
*d++ = *s++;
124
*d++ = *s++;
125
*d++ = *s++;
126
}
127
128
if (__n & 1 << 1) {
129
*d++ = *s++;
130
*d++ = *s++;
131
}
132
133
if (__n & 1)
134
*d++ = *s++;
135
136
return __dest;
137
}
138
139
/*
140
* gzip declarations
141
*/
142
extern char input_data[];
143
extern char input_data_end[];
144
145
unsigned char *output_data;
146
147
unsigned long free_mem_ptr;
148
unsigned long free_mem_end_ptr;
149
150
#ifndef arch_error
151
#define arch_error(x)
152
#endif
153
154
void error(char *x)
155
{
156
arch_error(x);
157
158
putstr("\n\n");
159
putstr(x);
160
putstr("\n\n -- System halted");
161
162
while(1); /* Halt */
163
}
164
165
asmlinkage void __div0(void)
166
{
167
error("Attempting division by 0!");
168
}
169
170
extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x));
171
172
173
void
174
decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
175
unsigned long free_mem_ptr_end_p,
176
int arch_id)
177
{
178
int ret;
179
180
output_data = (unsigned char *)output_start;
181
free_mem_ptr = free_mem_ptr_p;
182
free_mem_end_ptr = free_mem_ptr_end_p;
183
__machine_arch_type = arch_id;
184
185
arch_decomp_setup();
186
187
putstr("Uncompressing Linux...");
188
ret = do_decompress(input_data, input_data_end - input_data,
189
output_data, error);
190
if (ret)
191
error("decompressor returned an error");
192
else
193
putstr(" done, booting the kernel.\n");
194
}
195
196