4 * $Id: misc.c,v 1.2 1999/09/14 05:55:29 dmalek Exp $
6 * Adapted for PowerPC by Gary Thomas
8 * Rewritten by Cort Dougan (cort@cs.nmt.edu)
9 * One day to be replaced by a single bootloader for chrp/prep/pmac. -- Cort
12 #include <linux/types.h>
13 #include "../coffboot/zlib.h"
14 #include "asm/residual.h"
15 #include <linux/elf.h>
16 #include <linux/config.h>
18 #include <asm/processor.h>
21 #include <asm/mpc8xx.h>
24 #include <asm/mpc8260.h>
28 * The following references are needed to cause the linker to pull in the
29 * gzimage.o and rdimage.o files. These object files are special,
30 * since they get placed into the .gzimage and .rdimage ELF sections
31 * of the zvmlinux and zvmlinux.initrd files.
33 extern char dummy_for_gzimage
;
34 extern char dummy_for_rdimage
;
37 * Please send me load/board info and such data for hardware not
38 * listed here so I can keep track since things are getting tricky
39 * with the different load addrs with different firmware. This will
40 * help to avoid breaking the load/boot process.
46 /* See comment below.....
48 unsigned int initrd_offset
, initrd_size
;
50 /* Because of the limited amount of memory on embedded, it presents
51 * loading problems. The biggest is that we load this boot program
52 * into a relatively low memory address, and the Linux kernel Bss often
53 * extends into this space when it get loaded. When the kernel starts
54 * and zeros the BSS space, it also writes over the information we
55 * save here and pass to the kernel (command line and board info).
56 * On these boards, we grab some known memory holes to hold this information.
59 char *cmd_line
= cmd_buf
;
61 char *root_string
= "root=/dev/nfs rw";
62 char *nfsaddrs_string
= "nfsaddrs=";
63 char *nfsroot_string
= "nfsroot=";
64 char *defroot_string
= "/sys/mbxroot";
65 char *ramroot_string
= "root=/dev/ram";
66 int do_ipaddrs(char **cmd_cp
, int echo
);
67 void do_nfsroot(char **cmd_cp
, char *dp
);
68 int strncmp(const char * cs
,const char * ct
,size_t count
);
69 char *strrchr(const char * s
, int c
);
72 bd_t
*hold_residual
= &hold_resid_buf
;
73 unsigned long initrd_start
= 0, initrd_end
= 0;
77 void puts(const char *);
78 void putc(const char c
);
79 void puthex(unsigned long val
);
80 void _bcopy(char *src
, char *dst
, int len
);
81 void * memcpy(void * __dest
, __const
void * __src
,
83 void gunzip(void *, int, unsigned char *, int *);
96 /* The MPC8xx is just the serial port.
100 return (serial_tstc());
106 if (serial_tstc()) return (serial_getc());
116 void puts(const char *s
)
120 while ( ( c
= *s
++ ) != '\0' ) {
123 serial_putchar('\r');
127 void * memcpy(void * __dest
, __const
void * __src
,
131 char *d
= (char *)__dest
, *s
= (char *)__src
;
133 for (i
=0;i
<__n
;i
++) d
[i
] = s
[i
];
136 int memcmp(__const
void * __dest
, __const
void * __src
,
140 char *d
= (char *)__dest
, *s
= (char *)__src
;
142 for (i
=0;i
<__n
;i
++, d
++, s
++)
156 puts("\n\n -- System halted");
161 void *zalloc(void *x
, unsigned items
, unsigned size
)
166 size
= (size
+ 7) & -8;
168 if (avail_ram
> end_avail
) {
169 puts("oops... out of memory\n");
175 void zfree(void *x
, void *addr
, unsigned nb
)
180 #define EXTRA_FIELD 4
183 #define RESERVED 0xe0
188 void gunzip(void *dst
, int dstlen
, unsigned char *src
, int *lenp
)
196 if (src
[2] != DEFLATED
|| (flags
& RESERVED
) != 0) {
197 puts("bad gzipped data\n");
200 if ((flags
& EXTRA_FIELD
) != 0)
201 i
= 12 + src
[10] + (src
[11] << 8);
202 if ((flags
& ORIG_NAME
) != 0)
203 while (src
[i
++] != 0)
205 if ((flags
& COMMENT
) != 0)
206 while (src
[i
++] != 0)
208 if ((flags
& HEAD_CRC
) != 0)
211 puts("gunzip: ran out of data in header\n");
217 r
= inflateInit2(&s
, -MAX_WBITS
);
219 puts("inflateInit2 returned %d\n");
223 s
.avail_in
= *lenp
- i
;
225 s
.avail_out
= dstlen
;
226 r
= inflate(&s
, Z_FINISH
);
227 if (r
!= Z_OK
&& r
!= Z_STREAM_END
) {
228 puts("inflate returned %d\n");
231 *lenp
= s
.next_out
- (unsigned char *) dst
;
235 unsigned char sanity
[0x2000];
238 decompress_kernel(unsigned long load_addr
, int num_words
, unsigned long cksum
, bd_t
*bp
)
241 extern unsigned long start
;
247 /* I don't know why I didn't do it this way on the 8xx.......
253 /* These values must be variables. If not, the compiler optimizer
254 * will remove some code, causing the size of the code to vary
255 * when these values are zero. This is bad because we first
256 * compile with these zero to determine the size and offsets
257 * in an image, than compile again with these set to the proper
258 * discovered value.....Ya know, we used to read these from the
259 * header a long time ago.....
261 initrd_offset
= INITRD_OFFSET
;
262 initrd_size
= INITRD_SIZE
;
264 /* Grab some space for the command line and board info. Since
265 * we no longer use the ELF header, but it was loaded, grab
269 cmd_line
= (char *)(load_addr
- 0x10000);
271 cmd_line
= (char *)(0x200000);
273 hold_residual
= (bd_t
*)(cmd_line
+ sizeof(cmd_buf
));
274 /* copy board data */
276 memcpy(hold_residual
,bp
,sizeof(bd_t
));
278 /* Set end of memory available to us. It is always the highest
279 * memory address provided by the board information.
281 end_avail
= (char *)(bp
->bi_memsize
);
283 puts("loaded at: "); puthex(load_addr
);
284 puts(" "); puthex((unsigned long)(load_addr
+ (4*num_words
))); puts("\n");
285 if ( (unsigned long)load_addr
!= (unsigned long)&start
)
287 puts("relocated to: "); puthex((unsigned long)&start
);
289 puthex((unsigned long)((unsigned long)&start
+ (4*num_words
)));
295 puts("board data at: "); puthex((unsigned long)bp
);
297 puthex((unsigned long)((unsigned long)bp
+ sizeof(bd_t
)));
299 puts("relocated to: ");
300 puthex((unsigned long)hold_residual
);
302 puthex((unsigned long)((unsigned long)hold_residual
+ sizeof(bd_t
)));
306 /* we have to subtract 0x10000 here to correct for objdump including the
307 size of the elf header which we strip -- Cort */
308 zimage_start
= (char *)(load_addr
- 0x10000 + ZIMAGE_OFFSET
);
309 zimage_size
= ZIMAGE_SIZE
;
312 initrd_start
= load_addr
- 0x10000 + initrd_offset
;
315 initrd_end
= initrd_size
+ initrd_start
;
318 * setup avail_ram - this is the first part of ram usable
319 * by the uncompress code. -- Cort
321 avail_ram
= (char *)PAGE_ALIGN((unsigned long)zimage_start
+zimage_size
);
322 if ( ((load_addr
+(num_words
*4)) > (unsigned long) avail_ram
)
323 && (load_addr
<= 0x01000000) )
324 avail_ram
= (char *)(load_addr
+(num_words
*4));
325 if ( (((unsigned long)&start
+(num_words
*4)) > (unsigned long) avail_ram
)
326 && (load_addr
<= 0x01000000) )
327 avail_ram
= (char *)((unsigned long)&start
+(num_words
*4));
329 /* relocate zimage */
330 puts("zimage at: "); puthex((unsigned long)zimage_start
);
331 puts(" "); puthex((unsigned long)(zimage_size
+zimage_start
)); puts("\n");
333 * There is no reason (yet) to relocate zImage for embedded boards.
334 * To support boot from flash rom on 8xx embedded boards, I
335 * assume if zimage start is over 16M we are booting from flash.
336 * In this case, avilable ram will start just above the space we
337 * have allocated for the command buffer and board information.
339 if ((unsigned long)zimage_start
> 0x01000000)
340 avail_ram
= (char *)PAGE_ALIGN((unsigned long)hold_residual
+ sizeof(bd_t
));
342 /* relocate initrd */
345 puts("initrd at: "); puthex(initrd_start
);
346 puts(" "); puthex(initrd_end
); puts("\n");
348 /* We only have to relocate initrd if we find it is in Flash
349 * rom. This is because the kernel thinks it can toss the
350 * pages into the free memory pool after it is done. Use
353 if ((unsigned long)initrd_start
> 0x01000000) {
354 memcpy ((void *)PAGE_ALIGN(-PAGE_SIZE
+(unsigned long)end_avail
-INITRD_SIZE
),
355 (void *)initrd_start
,
357 initrd_start
= PAGE_ALIGN(-PAGE_SIZE
+(unsigned long)end_avail
-INITRD_SIZE
);
358 initrd_end
= initrd_start
+ initrd_size
;
359 end_avail
= (char *)initrd_start
;
360 puts("relocated to: "); puthex(initrd_start
);
361 puts(" "); puthex(initrd_end
); puts("\n");
364 avail_ram
= (char *)PAGE_ALIGN((unsigned long)initrd_end
);
369 puts("avail ram: "); puthex((unsigned long)avail_ram
); puts(" ");
370 puthex((unsigned long)end_avail
); puts("\n");
372 puts("\nLinux/PPC load: ");
376 while (timer
++ < 5*1000) {
378 while ((ch
= getc()) != '\n' && ch
!= '\r') {
380 if (cp
!= cmd_line
) {
389 break; /* Exit 'timer' loop */
391 udelay(1000); /* 1 msec */
395 /* If the command line is not filled in, we will automatically
396 * create the default boot.
398 if (cmd_line
[0] == 0) {
400 /* An initrd on these boards means we booted from Flash
401 * ROM and want to use the ramdisk as the root file system.
402 * Otherwise, we perform a diskless NFS boot.
415 puts("Uncompressing Linux...");
417 gunzip(0, 0x400000, zimage_start
, &zimage_size
);
419 puts("Now booting the kernel\n");
420 return (unsigned long)hold_residual
;
423 void puthex(unsigned long val
)
425 unsigned char buf
[10];
427 for (i
= 7; i
>= 0; i
--)
429 buf
[i
] = "0123456789ABCDEF"[val
& 0x0F];
437 * PCI/ISA I/O support
440 volatile unsigned char *ISA_io
= (unsigned char *)0x80000000;
441 volatile unsigned char *ISA_mem
= (unsigned char *)0xC0000000;
444 outb(int port
, char val
)
446 /* Ensure I/O operations complete */
447 __asm__
volatile("eieio");
454 /* Ensure I/O operations complete */
455 __asm__
volatile("eieio");
456 return (ISA_io
[port
]);
460 local_to_PCI(unsigned long addr
)
462 return ((addr
& 0x7FFFFFFF) | 0x80000000);
466 _bcopy(char *src
, char *dst
, int len
)
468 while (len
--) *dst
++ = *src
++;