aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc/boot/openfirmware
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/ppc/boot/openfirmware
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'arch/ppc/boot/openfirmware')
-rw-r--r--arch/ppc/boot/openfirmware/Makefile188
-rw-r--r--arch/ppc/boot/openfirmware/chrpmain.c101
-rw-r--r--arch/ppc/boot/openfirmware/coffmain.c101
-rw-r--r--arch/ppc/boot/openfirmware/common.c162
-rw-r--r--arch/ppc/boot/openfirmware/dummy.c4
-rw-r--r--arch/ppc/boot/openfirmware/misc.S67
-rw-r--r--arch/ppc/boot/openfirmware/newworldmain.c94
-rw-r--r--arch/ppc/boot/openfirmware/start.c172
8 files changed, 889 insertions, 0 deletions
diff --git a/arch/ppc/boot/openfirmware/Makefile b/arch/ppc/boot/openfirmware/Makefile
new file mode 100644
index 000000000000..4eacbd8c772a
--- /dev/null
+++ b/arch/ppc/boot/openfirmware/Makefile
@@ -0,0 +1,188 @@
1# Makefile for making bootable images on various OpenFirmware machines.
2#
3# Paul Mackerras January 1997
4# XCOFF bootable images for PowerMacs
5# Geert Uytterhoeven September 1997
6# ELF bootable iamges for CHRP machines.
7# Tom Rini January 2001
8# Cleaned up, moved into arch/ppc/boot/pmac
9# Tom Rini July/August 2002
10# Merged 'chrp' and 'pmac' into 'openfirmware', and cleaned up the
11# rules.
12
13zImage.initrd znetboot.initrd: del-ramdisk-sec := -R .ramdisk
14zImage.initrd znetboot.initrd: initrd := .initrd
15
16
17boot := arch/ppc/boot
18common := $(boot)/common
19utils := $(boot)/utils
20bootlib := $(boot)/lib
21of1275 := $(boot)/of1275
22images := $(boot)/images
23
24OBJCOPY_ARGS := -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment
25COFF_LD_ARGS := -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x00500000 \
26 -Bstatic
27CHRP_LD_ARGS := -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x00800000
28NEWWORLD_LD_ARGS:= -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x01000000
29
30COMMONOBJS := start.o misc.o common.o
31COFFOBJS := coffcrt0.o $(COMMONOBJS) coffmain.o
32CHRPOBJS := crt0.o $(COMMONOBJS) chrpmain.o
33NEWWORLDOBJS := crt0.o $(COMMONOBJS) newworldmain.o
34
35targets := $(COFFOBJS) $(CHRPOBJS) $(NEWWORLDOBJS) dummy.o
36COFFOBJS := $(addprefix $(obj)/, $(COFFOBJS))
37CHRPOBJS := $(addprefix $(obj)/, $(CHRPOBJS))
38NEWWORLDOBJS := $(addprefix $(obj)/, $(NEWWORLDOBJS))
39
40LIBS := lib/lib.a $(bootlib)/lib.a $(of1275)/lib.a $(common)/lib.a
41
42HACKCOFF := $(utils)/hack-coff
43
44ifdef CONFIG_SMP
45END := .smp
46endif
47ifdef CONFIG_PPC64BRIDGE
48END += .64
49endif
50
51
52$(images)/ramdisk.image.gz:
53 @echo ' MISSING $@'
54 @echo ' RAM disk image must be provided separately'
55 @/bin/false
56
57objcpxmon-$(CONFIG_XMON) := --add-section=.sysmap=System.map \
58 --set-section-flags=.sysmap=contents,alloc,load,readonly,data
59quiet_cmd_genimage = GEN $@
60 cmd_genimage = $(OBJCOPY) -R .comment \
61 --add-section=.image=$(images)/vmlinux.gz \
62 --set-section-flags=.image=contents,alloc,load,readonly,data \
63 $(objcpxmon-y) $< $@
64
65targets += image.o
66$(obj)/image.o: $(obj)/dummy.o $(images)/vmlinux.gz FORCE
67 $(call if_changed,genimage)
68
69# Place the ramdisk in the initrd image.
70quiet_cmd_genimage-initrd = GEN $@
71 cmd_genimage-initrd = $(OBJCOPY) $< $@ \
72 --add-section=.ramdisk=$(images)/ramdisk.image.gz \
73 --set-section-flags=.ramdisk=contents,alloc,load,readonly,data
74targets += image.initrd.o
75$(obj)/image.initrd.o: $(obj)/image.o $(images)/ramdisk.image.gz FORCE
76 $(call if_changed,genimage-initrd)
77
78# Create the note section for New-World PowerMacs.
79quiet_cmd_mknote = MKNOTE $@
80 cmd_mknote = $(utils)/mknote > $@
81targets += note
82$(obj)/note: $(utils)/mknote FORCE
83 $(call if_changed,mknote)
84
85
86$(obj)/coffcrt0.o: EXTRA_AFLAGS := -traditional -DXCOFF
87$(obj)/crt0.o: EXTRA_AFLAGS := -traditional
88targets += coffcrt0.o crt0.o
89$(obj)/coffcrt0.o $(obj)/crt0.o: $(common)/crt0.S FORCE
90 $(call if_changed_dep,as_o_S)
91
92quiet_cmd_gencoffb = COFF $@
93 cmd_gencoffb = $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) $< $(LIBS) && \
94 $(OBJCOPY) $@ $@ -R .comment $(del-ramdisk-sec)
95targets += coffboot
96$(obj)/coffboot: $(obj)/image.o $(COFFOBJS) $(LIBS) $(srctree)/$(boot)/ld.script FORCE
97 $(call if_changed,gencoffb)
98targets += coffboot.initrd
99$(obj)/coffboot.initrd: $(obj)/image.initrd.o $(COFFOBJS) $(LIBS) \
100 $(srctree)/$(boot)/ld.script FORCE
101 $(call if_changed,gencoffb)
102
103
104quiet_cmd_gen-coff = COFF $@
105 cmd_gen-coff = $(OBJCOPY) $(OBJCOPY_ARGS) $< $@ && \
106 $(HACKCOFF) $@ && \
107 ln -sf $(notdir $@) $(images)/zImage$(initrd).pmac
108
109$(images)/vmlinux.coff: $(obj)/coffboot
110 $(call cmd,gen-coff)
111
112$(images)/vmlinux.initrd.coff: $(obj)/coffboot.initrd
113 $(call cmd,gen-coff)
114
115quiet_cmd_gen-elf-pmac = ELF $@
116 cmd_gen-elf-pmac = $(LD) $(NEWWORLD_LD_ARGS) -o $@ \
117 $(NEWWORLDOBJS) $(LIBS) $< && \
118 $(OBJCOPY) $@ $@ --add-section=.note=$(obj)/note \
119 -R .comment $(del-ramdisk-sec)
120
121$(images)/vmlinux.elf-pmac: $(obj)/image.o $(NEWWORLDOBJS) $(LIBS) \
122 $(obj)/note $(srctree)/$(boot)/ld.script
123 $(call cmd,gen-elf-pmac)
124$(images)/vmlinux.initrd.elf-pmac: $(obj)/image.initrd.o $(NEWWORLDOBJS) \
125 $(LIBS) $(obj)/note \
126 $(srctree)/$(boot)/ld.script
127 $(call cmd,gen-elf-pmac)
128
129quiet_cmd_gen-chrp = CHRP $@
130 cmd_gen-chrp = $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) $< $(LIBS) && \
131 $(OBJCOPY) $@ $@ -R .comment $(del-ramdisk-sec)
132
133$(images)/zImage.chrp: $(obj)/image.o $(CHRPOBJS) $(LIBS) \
134 $(srctree)/$(boot)/ld.script
135 $(call cmd,gen-chrp)
136$(images)/zImage.initrd.chrp: $(obj)/image.initrd.o $(CHRPOBJS) $(LIBS) \
137 $(srctree)/$(boot)/ld.script
138 $(call cmd,gen-chrp)
139
140quiet_cmd_addnote = ADDNOTE $@
141 cmd_addnote = cat $< > $@ && $(utils)/addnote $@
142$(images)/zImage.chrp-rs6k $(images)/zImage.initrd.chrp-rs6k: \
143 %-rs6k: %
144 $(call cmd,addnote)
145
146quiet_cmd_gen-miboot = GEN $@
147 cmd_gen-miboot = $(OBJCOPY) $(OBJCOPY_ARGS) \
148 --add-section=$1=$(word 2, $^) $< $@
149$(images)/miboot.image: $(obj)/dummy.o $(images)/vmlinux.gz
150 $(call cmd,gen-miboot,image)
151
152$(images)/miboot.initrd.image: $(images)/miboot.image $(images)/ramdisk.image.gz
153 $(call cmd,gen-miboot,initrd)
154
155# The targets used on the make command-line
156
157.PHONY: zImage zImage.initrd
158zImage: $(images)/vmlinux.coff \
159 $(images)/vmlinux.elf-pmac \
160 $(images)/zImage.chrp \
161 $(images)/zImage.chrp-rs6k \
162 $(images)/miboot.image
163 @echo ' kernel: $@ is ready ($<)'
164zImage.initrd: $(images)/vmlinux.initrd.coff \
165 $(images)/vmlinux.initrd.elf-pmac \
166 $(images)/zImage.initrd.chrp \
167 $(images)/zImage.initrd.chrp-rs6k \
168 $(images)/miboot.initrd.image
169 @echo ' kernel: $@ is ready ($<)'
170
171TFTPIMAGE := /tftpboot/zImage
172
173.PHONY: znetboot znetboot.initrd
174znetboot: $(images)/vmlinux.coff \
175 $(images)/vmlinux.elf-pmac \
176 $(images)/zImage.chrp
177 cp $(images)/vmlinux.coff $(TFTPIMAGE).pmac$(END)
178 cp $(images)/vmlinux.elf-pmac $(TFTPIMAGE).pmac$(END).elf
179 cp $(images)/zImage.chrp $(TFTPIMAGE).chrp$(END)
180 @echo ' kernel: $@ is ready ($<)'
181znetboot.initrd:$(images)/vmlinux.initrd.coff \
182 $(images)/vmlinux.initrd.elf-pmac \
183 $(images)/zImage.initrd.chrp
184 cp $(images)/vmlinux.initrd.coff $(TFTPIMAGE).pmac$(END)
185 cp $(images)/vmlinux.initrd.elf-pmac $(TFTPIMAGE).pmac$(END).elf
186 cp $(images)/zImage.initrd.chrp $(TFTPIMAGE).chrp$(END)
187 @echo ' kernel: $@ is ready ($<)'
188
diff --git a/arch/ppc/boot/openfirmware/chrpmain.c b/arch/ppc/boot/openfirmware/chrpmain.c
new file mode 100644
index 000000000000..6fb4f738728c
--- /dev/null
+++ b/arch/ppc/boot/openfirmware/chrpmain.c
@@ -0,0 +1,101 @@
1/*
2 * Copyright (C) Paul Mackerras 1997.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9#include <linux/string.h>
10#include "nonstdio.h"
11#include "of1275.h"
12#include <asm/processor.h>
13#include <asm/page.h>
14
15/* Passed from the linker */
16extern char __image_begin, __image_end;
17extern char __ramdisk_begin, __ramdisk_end;
18extern char _start, _end;
19
20extern unsigned int heap_max;
21extern void flush_cache(void *, unsigned long);
22extern void gunzip(void *, int, unsigned char *, int *);
23extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
24 unsigned int progend);
25
26char *avail_ram;
27char *begin_avail, *end_avail;
28char *avail_high;
29
30#define RAM_START 0x00000000
31#define RAM_END (64<<20)
32
33#define BOOT_START ((unsigned long)_start)
34#define BOOT_END ((unsigned long)(_end + 0xFFF) & ~0xFFF)
35
36#define RAM_FREE ((unsigned long)(_end+0x1000)&~0xFFF)
37#define PROG_START 0x00010000
38#define PROG_SIZE 0x007f0000 /* 8MB */
39
40#define SCRATCH_SIZE (128 << 10)
41
42static char scratch[SCRATCH_SIZE]; /* 1MB of scratch space for gunzip */
43
44typedef void (*kernel_start_t)(int, int, void *, unsigned int, unsigned int);
45
46void
47boot(int a1, int a2, void *prom)
48{
49 unsigned sa, len;
50 void *dst;
51 unsigned char *im;
52 unsigned int initrd_size, initrd_start;
53
54 printf("chrpboot starting: loaded at 0x%p\n\r", &_start);
55
56 initrd_size = &__ramdisk_end - &__ramdisk_begin;
57 if (initrd_size) {
58 initrd_start = (RAM_END - initrd_size) & ~0xFFF;
59 a1 = initrd_start;
60 a2 = initrd_size;
61 claim(initrd_start, RAM_END - initrd_start, 0);
62 printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r",
63 initrd_start, &__ramdisk_begin, initrd_size);
64 memcpy((char *)initrd_start, &__ramdisk_begin, initrd_size);
65 } else {
66 initrd_start = 0;
67 initrd_size = 0;
68 a2 = 0xdeadbeef;
69 }
70
71 im = &__image_begin;
72 len = &__image_end - &__image_begin;
73 /* claim 4MB starting at PROG_START */
74 claim(PROG_START, PROG_SIZE - PROG_START, 0);
75 dst = (void *) PROG_START;
76 if (im[0] == 0x1f && im[1] == 0x8b) {
77 avail_ram = scratch;
78 begin_avail = avail_high = avail_ram;
79 end_avail = scratch + sizeof(scratch);
80 printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len);
81 gunzip(dst, 0x400000, im, &len);
82 printf("done %u bytes\n\r", len);
83 printf("%u bytes of heap consumed, max in use %u\n\r",
84 avail_high - begin_avail, heap_max);
85 } else {
86 memmove(dst, im, len);
87 }
88
89 flush_cache(dst, len);
90 make_bi_recs(((unsigned long) dst + len), "chrpboot", _MACH_chrp,
91 (PROG_START + PROG_SIZE));
92
93 sa = PROG_START;
94 printf("start address = 0x%x\n\r", sa);
95
96 (*(kernel_start_t)sa)(a1, a2, prom, initrd_start, initrd_size);
97
98 printf("returned?\n\r");
99
100 pause();
101}
diff --git a/arch/ppc/boot/openfirmware/coffmain.c b/arch/ppc/boot/openfirmware/coffmain.c
new file mode 100644
index 000000000000..04ba9d57e110
--- /dev/null
+++ b/arch/ppc/boot/openfirmware/coffmain.c
@@ -0,0 +1,101 @@
1/*
2 * Copyright (C) Paul Mackerras 1997.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9#include <linux/string.h>
10#include <asm/processor.h>
11#include <asm/page.h>
12
13#include "nonstdio.h"
14#include "of1275.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 char image_data[], initrd_data[];
22extern int initrd_len, image_len;
23extern unsigned int heap_max;
24extern void flush_cache(void *start, unsigned int len);
25extern void gunzip(void *, int, unsigned char *, int *);
26extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
27 unsigned int progend);
28extern void setup_bats(unsigned long start);
29
30char *avail_ram;
31char *begin_avail, *end_avail;
32char *avail_high;
33
34#define SCRATCH_SIZE (128 << 10)
35
36static char heap[SCRATCH_SIZE];
37
38static unsigned long ram_start = 0;
39static unsigned long ram_end = 0x1000000;
40
41static unsigned long prog_start = 0x900000;
42static unsigned long prog_size = 0x700000;
43
44typedef void (*kernel_start_t)(int, int, void *);
45
46void boot(int a1, int a2, void *prom)
47{
48 unsigned sa, len;
49 void *dst;
50 unsigned char *im;
51 unsigned initrd_start, initrd_size;
52
53 printf("coffboot starting: loaded at 0x%p\n", &_start);
54 setup_bats(ram_start);
55
56 initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin);
57 if (initrd_size) {
58 initrd_start = (ram_end - initrd_size) & ~0xFFF;
59 a1 = initrd_start;
60 a2 = initrd_size;
61 claim(initrd_start, ram_end - initrd_start, 0);
62 printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r",
63 initrd_start, (char *)(&__ramdisk_begin), initrd_size);
64 memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size);
65 prog_size = initrd_start - prog_start;
66 } else
67 a2 = 0xdeadbeef;
68
69 im = (char *)(&__image_begin);
70 len = (char *)(&__image_end) - (char *)(&__image_begin);
71 /* claim 4MB starting at PROG_START */
72 claim(prog_start, prog_size, 0);
73 map(prog_start, prog_start, prog_size);
74 dst = (void *) prog_start;
75 if (im[0] == 0x1f && im[1] == 0x8b) {
76 /* set up scratch space */
77 begin_avail = avail_high = avail_ram = heap;
78 end_avail = heap + sizeof(heap);
79 printf("heap at 0x%p\n", avail_ram);
80 printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len);
81 gunzip(dst, prog_size, im, &len);
82 printf("done %u bytes\n", len);
83 printf("%u bytes of heap consumed, max in use %u\n",
84 avail_high - begin_avail, heap_max);
85 } else {
86 memmove(dst, im, len);
87 }
88
89 flush_cache(dst, len);
90 make_bi_recs(((unsigned long) dst + len), "coffboot", _MACH_Pmac,
91 (prog_start + prog_size));
92
93 sa = (unsigned long)prog_start;
94 printf("start address = 0x%x\n", sa);
95
96 (*(kernel_start_t)sa)(a1, a2, prom);
97
98 printf("returned?\n");
99
100 pause();
101}
diff --git a/arch/ppc/boot/openfirmware/common.c b/arch/ppc/boot/openfirmware/common.c
new file mode 100644
index 000000000000..9e6952781f1f
--- /dev/null
+++ b/arch/ppc/boot/openfirmware/common.c
@@ -0,0 +1,162 @@
1/*
2 * Copyright (C) Paul Mackerras 1997.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#include "nonstdio.h"
11#include "of1275.h"
12#include <linux/string.h>
13#include <linux/zlib.h>
14#include <asm/bootinfo.h>
15#include <asm/page.h>
16
17/* Information from the linker */
18extern char __sysmap_begin, __sysmap_end;
19
20extern int strcmp(const char *s1, const char *s2);
21extern char *avail_ram, *avail_high;
22extern char *end_avail;
23
24unsigned int heap_use, heap_max;
25
26struct memchunk {
27 unsigned int size;
28 struct memchunk *next;
29};
30
31static struct memchunk *freechunks;
32
33static void *zalloc(unsigned size)
34{
35 void *p;
36 struct memchunk **mpp, *mp;
37
38 size = (size + 7) & -8;
39 heap_use += size;
40 if (heap_use > heap_max)
41 heap_max = heap_use;
42 for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
43 if (mp->size == size) {
44 *mpp = mp->next;
45 return mp;
46 }
47 }
48 p = avail_ram;
49 avail_ram += size;
50 if (avail_ram > avail_high)
51 avail_high = avail_ram;
52 if (avail_ram > end_avail) {
53 printf("oops... out of memory\n\r");
54 pause();
55 }
56 return p;
57}
58
59#define HEAD_CRC 2
60#define EXTRA_FIELD 4
61#define ORIG_NAME 8
62#define COMMENT 0x10
63#define RESERVED 0xe0
64
65void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
66{
67 z_stream s;
68 int r, i, flags;
69
70 /* skip header */
71 i = 10;
72 flags = src[3];
73 if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) {
74 printf("bad gzipped data\n\r");
75 exit();
76 }
77 if ((flags & EXTRA_FIELD) != 0)
78 i = 12 + src[10] + (src[11] << 8);
79 if ((flags & ORIG_NAME) != 0)
80 while (src[i++] != 0)
81 ;
82 if ((flags & COMMENT) != 0)
83 while (src[i++] != 0)
84 ;
85 if ((flags & HEAD_CRC) != 0)
86 i += 2;
87 if (i >= *lenp) {
88 printf("gunzip: ran out of data in header\n\r");
89 exit();
90 }
91
92 /* Initialize ourself. */
93 s.workspace = zalloc(zlib_inflate_workspacesize());
94 r = zlib_inflateInit2(&s, -MAX_WBITS);
95 if (r != Z_OK) {
96 printf("zlib_inflateInit2 returned %d\n\r", r);
97 exit();
98 }
99 s.next_in = src + i;
100 s.avail_in = *lenp - i;
101 s.next_out = dst;
102 s.avail_out = dstlen;
103 r = zlib_inflate(&s, Z_FINISH);
104 if (r != Z_OK && r != Z_STREAM_END) {
105 printf("inflate returned %d msg: %s\n\r", r, s.msg);
106 exit();
107 }
108 *lenp = s.next_out - (unsigned char *) dst;
109 zlib_inflateEnd(&s);
110}
111
112/* Make a bi_rec in OF. We need to be passed a name for BI_BOOTLOADER_ID,
113 * a machine type for BI_MACHTYPE, and the location where the end of the
114 * bootloader is (PROG_START + PROG_SIZE)
115 */
116void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
117 unsigned long progend)
118{
119 unsigned long sysmap_size;
120 struct bi_record *rec;
121
122 /* Figure out the size of a possible System.map we're going to
123 * pass along.
124 * */
125 sysmap_size = (unsigned long)(&__sysmap_end) -
126 (unsigned long)(&__sysmap_begin);
127
128 /* leave a 1MB gap then align to the next 1MB boundary */
129 addr = _ALIGN(addr+ (1<<20) - 1, (1<<20));
130 /* oldworld machine seem very unhappy about this. -- Tom */
131 if (addr >= progend)
132 claim(addr, 0x1000, 0);
133
134 rec = (struct bi_record *)addr;
135 rec->tag = BI_FIRST;
136 rec->size = sizeof(struct bi_record);
137 rec = (struct bi_record *)((unsigned long)rec + rec->size);
138
139 rec->tag = BI_BOOTLOADER_ID;
140 sprintf( (char *)rec->data, name);
141 rec->size = sizeof(struct bi_record) + strlen(name) + 1;
142 rec = (struct bi_record *)((unsigned long)rec + rec->size);
143
144 rec->tag = BI_MACHTYPE;
145 rec->data[0] = mach;
146 rec->data[1] = 1;
147 rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long);
148 rec = (struct bi_record *)((unsigned long)rec + rec->size);
149
150 if (sysmap_size) {
151 rec->tag = BI_SYSMAP;
152 rec->data[0] = (unsigned long)(&__sysmap_begin);
153 rec->data[1] = sysmap_size;
154 rec->size = sizeof(struct bi_record) + 2 *
155 sizeof(unsigned long);
156 rec = (struct bi_record *)((unsigned long)rec + rec->size);
157 }
158
159 rec->tag = BI_LAST;
160 rec->size = sizeof(struct bi_record);
161 rec = (struct bi_record *)((unsigned long)rec + rec->size);
162}
diff --git a/arch/ppc/boot/openfirmware/dummy.c b/arch/ppc/boot/openfirmware/dummy.c
new file mode 100644
index 000000000000..31dbf45bf99c
--- /dev/null
+++ b/arch/ppc/boot/openfirmware/dummy.c
@@ -0,0 +1,4 @@
1int main(void)
2{
3 return 0;
4}
diff --git a/arch/ppc/boot/openfirmware/misc.S b/arch/ppc/boot/openfirmware/misc.S
new file mode 100644
index 000000000000..ab9e897cadd0
--- /dev/null
+++ b/arch/ppc/boot/openfirmware/misc.S
@@ -0,0 +1,67 @@
1/*
2 * Copyright (C) Paul Mackerras 1997.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9 .text
10
11/*
12 * Use the BAT2 & 3 registers to map the 1st 16MB of RAM to
13 * the address given as the 1st argument.
14 */
15 .globl setup_bats
16setup_bats:
17 mfpvr 5
18 rlwinm 5,5,16,16,31 /* r3 = 1 for 601, 4 for 604 */
19 cmpwi 0,5,1
20 li 0,0
21 bne 4f
22 mtibatl 3,0 /* invalidate BAT first */
23 ori 3,3,4 /* set up BAT registers for 601 */
24 li 4,0x7f
25 mtibatu 2,3
26 mtibatl 2,4
27 oris 3,3,0x80
28 oris 4,4,0x80
29 mtibatu 3,3
30 mtibatl 3,4
31 b 5f
324: mtdbatu 3,0 /* invalidate BATs first */
33 mtibatu 3,0
34 ori 3,3,0xff /* set up BAT registers for 604 */
35 li 4,2
36 mtdbatl 2,4
37 mtdbatu 2,3
38 mtibatl 2,4
39 mtibatu 2,3
40 oris 3,3,0x80
41 oris 4,4,0x80
42 mtdbatl 3,4
43 mtdbatu 3,3
44 mtibatl 3,4
45 mtibatu 3,3
465: sync
47 isync
48 blr
49
50/*
51 * Flush the dcache and invalidate the icache for a range of addresses.
52 *
53 * flush_cache(addr, len)
54 */
55 .global flush_cache
56flush_cache:
57 addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */
58 rlwinm. 4,4,27,5,31
59 mtctr 4
60 beqlr
611: dcbf 0,3
62 icbi 0,3
63 addi 3,3,0x20
64 bdnz 1b
65 sync
66 isync
67 blr
diff --git a/arch/ppc/boot/openfirmware/newworldmain.c b/arch/ppc/boot/openfirmware/newworldmain.c
new file mode 100644
index 000000000000..fa8a8f9313f9
--- /dev/null
+++ b/arch/ppc/boot/openfirmware/newworldmain.c
@@ -0,0 +1,94 @@
1/*
2 * Copyright (C) Paul Mackerras 1997.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9#include <linux/string.h>
10#include "nonstdio.h"
11#include "of1275.h"
12#include <asm/processor.h>
13#include <asm/page.h>
14
15/* Passed from the linker */
16extern char __image_begin, __image_end;
17extern char __ramdisk_begin[], __ramdisk_end;
18extern char _start, _end;
19
20extern unsigned int heap_max;
21extern void flush_cache(void *start, unsigned int len);
22extern void gunzip(void *, int, unsigned char *, int *);
23extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
24 unsigned int progend);
25
26char *avail_ram;
27char *begin_avail, *end_avail;
28char *avail_high;
29
30
31#define RAM_END (16 << 20)
32
33#define PROG_START 0x00010000
34#define PROG_SIZE 0x007f0000
35
36#define SCRATCH_SIZE (128 << 10)
37
38typedef void (*kernel_start_t)(int, int, void *);
39
40void boot(int a1, int a2, void *prom)
41{
42 unsigned sa, len;
43 void *dst;
44 unsigned char *im;
45 unsigned initrd_start, initrd_size;
46
47 printf("chrpboot starting: loaded at 0x%p\n", &_start);
48
49 initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin);
50 if (initrd_size) {
51 initrd_start = (RAM_END - initrd_size) & ~0xFFF;
52 a1 = initrd_start;
53 a2 = initrd_size;
54 claim(initrd_start, RAM_END - initrd_start, 0);
55 printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r",
56 initrd_start, (char *)(&__ramdisk_begin), initrd_size);
57 memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size);
58 } else
59 a2 = 0xdeadbeef;
60
61 im = (char *)(&__image_begin);
62 len = (char *)(&__image_end) - (char *)(&__image_begin);
63 /* claim 3MB starting at PROG_START */
64 claim(PROG_START, PROG_SIZE, 0);
65 dst = (void *) PROG_START;
66 if (im[0] == 0x1f && im[1] == 0x8b) {
67 /* claim some memory for scratch space */
68 avail_ram = (char *) claim(0, SCRATCH_SIZE, 0x10);
69 begin_avail = avail_high = avail_ram;
70 end_avail = avail_ram + SCRATCH_SIZE;
71 printf("heap at 0x%p\n", avail_ram);
72 printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len);
73 gunzip(dst, PROG_SIZE, im, &len);
74 printf("done %u bytes\n", len);
75 printf("%u bytes of heap consumed, max in use %u\n",
76 avail_high - begin_avail, heap_max);
77 release(begin_avail, SCRATCH_SIZE);
78 } else {
79 memmove(dst, im, len);
80 }
81
82 flush_cache(dst, len);
83 make_bi_recs(((unsigned long) dst + len), "chrpboot", _MACH_Pmac,
84 (PROG_START + PROG_SIZE));
85
86 sa = (unsigned long)PROG_START;
87 printf("start address = 0x%x\n", sa);
88
89 (*(kernel_start_t)sa)(a1, a2, prom);
90
91 printf("returned?\n");
92
93 pause();
94}
diff --git a/arch/ppc/boot/openfirmware/start.c b/arch/ppc/boot/openfirmware/start.c
new file mode 100644
index 000000000000..1617a26956bf
--- /dev/null
+++ b/arch/ppc/boot/openfirmware/start.c
@@ -0,0 +1,172 @@
1/*
2 * Copyright (C) Paul Mackerras 1997.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9#include <stdarg.h>
10#include "of1275.h"
11
12extern int strlen(const char *s);
13extern void boot(int a1, int a2, void *prom);
14
15phandle stdin;
16phandle stdout;
17phandle stderr;
18
19void printk(char *fmt, ...);
20
21void
22start(int a1, int a2, void *promptr)
23{
24 ofinit(promptr);
25 if (ofstdio(&stdin, &stdout, &stderr))
26 exit();
27
28 boot(a1, a2, promptr);
29 for (;;)
30 exit();
31}
32
33int writestring(void *f, char *ptr, int nb)
34{
35 int w = 0, i;
36 char *ret = "\r";
37
38 for (i = 0; i < nb; ++i) {
39 if (ptr[i] == '\n') {
40 if (i > w) {
41 write(f, ptr + w, i - w);
42 w = i;
43 }
44 write(f, ret, 1);
45 }
46 }
47 if (w < nb)
48 write(f, ptr + w, nb - w);
49 return nb;
50}
51
52int
53putc(int c, void *f)
54{
55 char ch = c;
56
57 return writestring(f, &ch, 1) == 1? c: -1;
58}
59
60int
61putchar(int c)
62{
63 return putc(c, stdout);
64}
65
66int
67fputs(char *str, void *f)
68{
69 int n = strlen(str);
70
71 return writestring(f, str, n) == n? 0: -1;
72}
73
74int
75readchar(void)
76{
77 char ch;
78
79 for (;;) {
80 switch (read(stdin, &ch, 1)) {
81 case 1:
82 return ch;
83 case -1:
84 printk("read(stdin) returned -1\n");
85 return -1;
86 }
87 }
88}
89
90static char line[256];
91static char *lineptr;
92static int lineleft;
93
94int
95getchar(void)
96{
97 int c;
98
99 if (lineleft == 0) {
100 lineptr = line;
101 for (;;) {
102 c = readchar();
103 if (c == -1 || c == 4)
104 break;
105 if (c == '\r' || c == '\n') {
106 *lineptr++ = '\n';
107 putchar('\n');
108 break;
109 }
110 switch (c) {
111 case 0177:
112 case '\b':
113 if (lineptr > line) {
114 putchar('\b');
115 putchar(' ');
116 putchar('\b');
117 --lineptr;
118 }
119 break;
120 case 'U' & 0x1F:
121 while (lineptr > line) {
122 putchar('\b');
123 putchar(' ');
124 putchar('\b');
125 --lineptr;
126 }
127 break;
128 default:
129 if (lineptr >= &line[sizeof(line) - 1])
130 putchar('\a');
131 else {
132 putchar(c);
133 *lineptr++ = c;
134 }
135 }
136 }
137 lineleft = lineptr - line;
138 lineptr = line;
139 }
140 if (lineleft == 0)
141 return -1;
142 --lineleft;
143 return *lineptr++;
144}
145
146extern int vsprintf(char *buf, const char *fmt, va_list args);
147static char sprint_buf[1024];
148
149void
150printk(char *fmt, ...)
151{
152 va_list args;
153 int n;
154
155 va_start(args, fmt);
156 n = vsprintf(sprint_buf, fmt, args);
157 va_end(args);
158 writestring(stdout, sprint_buf, n);
159}
160
161int
162printf(char *fmt, ...)
163{
164 va_list args;
165 int n;
166
167 va_start(args, fmt);
168 n = vsprintf(sprint_buf, fmt, args);
169 va_end(args);
170 writestring(stdout, sprint_buf, n);
171 return n;
172}