1/*
2 * BK Id: SCCS/s.chrpmain.c 1.18 01/11/02 10:46:07 trini
3 */
4/*
5 * Copyright (C) Paul Mackerras 1997.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 */
12#include "nonstdio.h"
13#include <asm/processor.h>
14#include <asm/page.h>
15
16/* Passed from the linker */
17extern char __image_begin, __image_end;
18extern char __ramdisk_begin[], __ramdisk_end;
19extern char _start, _end;
20
21extern int getprop(void *, const char *, void *, int);
22extern unsigned int heap_max;
23extern void *claim(unsigned int virt, unsigned int size, unsigned int align);
24extern void *finddevice(const char *);
25extern void flush_cache(void *start, unsigned int len);
26extern void gunzip(void *, int, unsigned char *, int *);
27extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
28		unsigned int progend);
29extern void pause(void);
30extern void release(void *ptr, unsigned int len);
31
32char *avail_ram;
33char *begin_avail, *end_avail;
34char *avail_high;
35
36
37#define RAM_END		(16 << 20)
38
39#define PROG_START	0x00010000
40#define PROG_SIZE	0x003f0000
41
42#define SCRATCH_SIZE	(128 << 10)
43
44void boot(int a1, int a2, void *prom)
45{
46    unsigned sa, len;
47    void *dst;
48    unsigned char *im;
49    unsigned initrd_start, initrd_size;
50
51    printf("chrpboot starting: loaded at 0x%p\n", &_start);
52
53    initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin);
54    if (initrd_size) {
55	initrd_start = (RAM_END - initrd_size) & ~0xFFF;
56	a1 = initrd_start;
57	a2 = initrd_size;
58	claim(initrd_start, RAM_END - initrd_start, 0);
59	printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r",
60	       initrd_start, (char *)(&__ramdisk_begin), initrd_size);
61	memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size);
62    } else
63	a2 = 0xdeadbeef;
64
65    im = (char *)(&__image_begin);
66    len = (char *)(&__image_end) - (char *)(&__image_begin);
67    /* claim 3MB starting at PROG_START */
68    claim(PROG_START, PROG_SIZE, 0);
69    dst = (void *) PROG_START;
70    if (im[0] == 0x1f && im[1] == 0x8b) {
71	/* claim some memory for scratch space */
72	avail_ram = (char *) claim(0, SCRATCH_SIZE, 0x10);
73	begin_avail = avail_high = avail_ram;
74	end_avail = avail_ram + SCRATCH_SIZE;
75	printf("heap at 0x%p\n", avail_ram);
76	printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len);
77	gunzip(dst, PROG_SIZE, im, &len);
78	printf("done %u bytes\n", len);
79	printf("%u bytes of heap consumed, max in use %u\n",
80	       avail_high - begin_avail, heap_max);
81	release(begin_avail, SCRATCH_SIZE);
82    } else {
83	memmove(dst, im, len);
84    }
85
86    flush_cache(dst, len);
87    make_bi_recs(((unsigned long) dst + len), "chrpboot", _MACH_Pmac,
88		    (PROG_START + PROG_SIZE));
89
90    sa = (unsigned long)PROG_START;
91    printf("start address = 0x%x\n", sa);
92
93    (*(void (*)())sa)(a1, a2, prom);
94
95    printf("returned?\n");
96
97    pause();
98}
99