diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/ppc/boot |
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')
85 files changed, 13219 insertions, 0 deletions
diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile new file mode 100644 index 00000000000..995f89bb049 --- /dev/null +++ b/arch/ppc/boot/Makefile @@ -0,0 +1,34 @@ +# +# arch/ppc/boot/Makefile +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 1994 by Linus Torvalds +# Adapted for PowerPC by Gary Thomas +# modified by Cort (cort@cs.nmt.edu) +# + +CFLAGS += -fno-builtin -D__BOOTER__ -Iarch/$(ARCH)/boot/include +HOSTCFLAGS += -Iarch/$(ARCH)/boot/include + +BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd + +bootdir-y := simple +bootdir-$(CONFIG_PPC_OF) += openfirmware +subdir-y := lib common images +subdir-$(CONFIG_PPC_OF) += of1275 + +# for cleaning +subdir- += simple openfirmware + +hostprogs-y := $(addprefix utils/, addnote mknote hack-coff mkprep mkbugboot mktree) + +.PHONY: $(BOOT_TARGETS) $(bootdir-y) + +$(BOOT_TARGETS): $(bootdir-y) + +$(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \ + $(addprefix $(obj)/,$(hostprogs-y)) + $(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS) diff --git a/arch/ppc/boot/common/Makefile b/arch/ppc/boot/common/Makefile new file mode 100644 index 00000000000..f88d647d5dd --- /dev/null +++ b/arch/ppc/boot/common/Makefile @@ -0,0 +1,13 @@ +# +# arch/ppc/boot/common/Makefile +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Tom Rini January 2001 +# + +lib-y := string.o util.o misc-common.o \ + serial_stub.o bootinfo.o +lib-$(CONFIG_SERIAL_8250_CONSOLE) += ns16550.o diff --git a/arch/ppc/boot/common/bootinfo.c b/arch/ppc/boot/common/bootinfo.c new file mode 100644 index 00000000000..9c6e528940e --- /dev/null +++ b/arch/ppc/boot/common/bootinfo.c @@ -0,0 +1,70 @@ +/* + * arch/ppc/common/bootinfo.c + * + * General bootinfo record utilities + * Author: Randy Vinson <rvinson@mvista.com> + * + * 2002 (c) MontaVista Software, Inc. This file is licensed under the terms + * of the GNU General Public License version 2. This program is licensed + * "as is" without any warranty of any kind, whether express or implied. + */ + +#include <linux/types.h> +#include <linux/string.h> +#include <asm/bootinfo.h> + +#include "nonstdio.h" + +static struct bi_record * birec = NULL; + +static struct bi_record * +__bootinfo_build(struct bi_record *rec, unsigned long tag, unsigned long size, + void *data) +{ + /* set the tag */ + rec->tag = tag; + + /* if the caller has any data, copy it */ + if (size) + memcpy(rec->data, (char *)data, size); + + /* set the record size */ + rec->size = sizeof(struct bi_record) + size; + + /* advance to the next available space */ + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + return rec; +} + +void +bootinfo_init(struct bi_record *rec) +{ + + /* save start of birec area */ + birec = rec; + + /* create an empty list */ + rec = __bootinfo_build(rec, BI_FIRST, 0, NULL); + (void) __bootinfo_build(rec, BI_LAST, 0, NULL); + +} + +void +bootinfo_append(unsigned long tag, unsigned long size, void * data) +{ + + struct bi_record *rec = birec; + + /* paranoia */ + if ((rec == NULL) || (rec->tag != BI_FIRST)) + return; + + /* find the last entry in the list */ + while (rec->tag != BI_LAST) + rec = (struct bi_record *)((ulong)rec + rec->size); + + /* overlay BI_LAST record with new one and tag on a new BI_LAST */ + rec = __bootinfo_build(rec, tag, size, data); + (void) __bootinfo_build(rec, BI_LAST, 0, NULL); +} diff --git a/arch/ppc/boot/common/crt0.S b/arch/ppc/boot/common/crt0.S new file mode 100644 index 00000000000..4d31b824bbd --- /dev/null +++ b/arch/ppc/boot/common/crt0.S @@ -0,0 +1,81 @@ +/* Copyright (c) 1997 Paul Mackerras <paulus@cs.anu.edu.au> + * Initial Power Macintosh COFF version. + * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> + * Modifications for IBM PowerPC 400-class processor evaluation + * boards. + * + * Module name: crt0.S + * + * Description: + * Boot loader execution entry point. Clears out .bss section as per + * ANSI C requirements. Invalidates and flushes the caches over the + * range covered by the boot loader's .text section. Sets up a stack + * below the .text section entry point. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include <linux/config.h> +#include <asm/ppc_asm.h> + + .text + + .globl _start +_start: +#ifdef XCOFF + .long __start,0,0 + + .globl __start +__start: +#endif + + ## Flush and invalidate the caches for the range in memory covering + ## the .text section of the boot loader + + lis r9,_start@h # r9 = &_start + lis r8,_etext@ha # + addi r8,r8,_etext@l # r8 = &_etext +3: dcbf r0,r9 # Flush the data cache + icbi r0,r9 # Invalidate the instruction cache + addi r9,r9,0x10 # Increment by one cache line + cmplw cr0,r9,r8 # Are we at the end yet? + blt 3b # No, keep flushing and invalidating + sync # sync ; isync after flushing the icache + isync + + ## Clear out the BSS as per ANSI C requirements + + lis r7,_end@ha + addi r7,r7,_end@l # r7 = &_end + lis r8,__bss_start@ha # + addi r8,r8,__bss_start@l # r8 = &_bss_start + + ## Determine how large an area, in number of words, to clear + + subf r7,r8,r7 # r7 = &_end - &_bss_start + 1 + addi r7,r7,3 # r7 += 3 + srwi. r7,r7,2 # r7 = size in words. + beq 2f # If the size is zero, do not bother + addi r8,r8,-4 # r8 -= 4 + mtctr r7 # SPRN_CTR = number of words to clear + li r0,0 # r0 = 0 +1: stwu r0,4(r8) # Clear out a word + bdnz 1b # If we are not done yet, keep clearing +2: + +#ifdef CONFIG_40x + ## Set up the stack + + lis r9,_start@h # r9 = &_start (text section entry) + ori r9,r9,_start@l + subi r1,r9,64 # Start the stack 64 bytes below _start + clrrwi r1,r1,4 # Make sure it is aligned on 16 bytes. + li r0,0 + stwu r0,-16(r1) + mtlr r9 +#endif + + b start # All done, start the real work. diff --git a/arch/ppc/boot/common/misc-common.c b/arch/ppc/boot/common/misc-common.c new file mode 100644 index 00000000000..e79e6b3f276 --- /dev/null +++ b/arch/ppc/boot/common/misc-common.c @@ -0,0 +1,553 @@ +/* + * arch/ppc/boot/common/misc-common.c + * + * Misc. bootloader code (almost) all platforms can use + * + * Author: Johnnie Peters <jpeters@mvista.com> + * Editor: Tom Rini <trini@mvista.com> + * + * Derived from arch/ppc/boot/prep/misc.c + * + * 2000-2001 (c) MontaVista, Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#include <stdarg.h> /* for va_ bits */ +#include <linux/config.h> +#include <linux/string.h> +#include <linux/zlib.h> +#include "nonstdio.h" + +/* If we're on a PReP, assume we have a keyboard controller + * Also note, if we're not PReP, we assume you are a serial + * console - Tom */ +#if defined(CONFIG_PPC_PREP) && defined(CONFIG_VGA_CONSOLE) +extern void cursor(int x, int y); +extern void scroll(void); +extern char *vidmem; +extern int lines, cols; +extern int orig_x, orig_y; +extern int keyb_present; +extern int CRT_tstc(void); +extern int CRT_getc(void); +#else +int cursor(int x, int y) {return 0;} +void scroll(void) {} +char vidmem[1]; +#define lines 0 +#define cols 0 +int orig_x = 0; +int orig_y = 0; +#define keyb_present 0 +int CRT_tstc(void) {return 0;} +int CRT_getc(void) {return 0;} +#endif + +extern char *avail_ram; +extern char *end_avail; +extern char _end[]; + +void puts(const char *); +void putc(const char c); +void puthex(unsigned long val); +void gunzip(void *, int, unsigned char *, int *); +static int _cvt(unsigned long val, char *buf, long radix, char *digits); + +void _vprintk(void(*putc)(const char), const char *fmt0, va_list ap); +unsigned char *ISA_io = NULL; + +#if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \ + || defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \ + || defined(CONFIG_SERIAL_MPSC_CONSOLE) +extern unsigned long com_port; + +extern int serial_tstc(unsigned long com_port); +extern unsigned char serial_getc(unsigned long com_port); +extern void serial_putc(unsigned long com_port, unsigned char c); +#endif + +void pause(void) +{ + puts("pause\n"); +} + +void exit(void) +{ + puts("exit\n"); + while(1); +} + +int tstc(void) +{ +#if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \ + || defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \ + || defined(CONFIG_SERIAL_MPSC_CONSOLE) + if(keyb_present) + return (CRT_tstc() || serial_tstc(com_port)); + else + return (serial_tstc(com_port)); +#else + return CRT_tstc(); +#endif +} + +int getc(void) +{ + while (1) { +#if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \ + || defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \ + || defined(CONFIG_SERIAL_MPSC_CONSOLE) + if (serial_tstc(com_port)) + return (serial_getc(com_port)); +#endif /* serial console */ + if (keyb_present) + if(CRT_tstc()) + return (CRT_getc()); + } +} + +void +putc(const char c) +{ + int x,y; + +#if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \ + || defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \ + || defined(CONFIG_SERIAL_MPSC_CONSOLE) + serial_putc(com_port, c); + if ( c == '\n' ) + serial_putc(com_port, '\r'); +#endif /* serial console */ + + x = orig_x; + y = orig_y; + + if ( c == '\n' ) { + x = 0; + if ( ++y >= lines ) { + scroll(); + y--; + } + } else if (c == '\r') { + x = 0; + } else if (c == '\b') { + if (x > 0) { + x--; + } + } else { + vidmem [ ( x + cols * y ) * 2 ] = c; + if ( ++x >= cols ) { + x = 0; + if ( ++y >= lines ) { + scroll(); + y--; + } + } + } + + cursor(x, y); + + orig_x = x; + orig_y = y; +} + +void puts(const char *s) +{ + int x,y; + char c; + + x = orig_x; + y = orig_y; + + while ( ( c = *s++ ) != '\0' ) { +#if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \ + || defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \ + || defined(CONFIG_SERIAL_MPSC_CONSOLE) + serial_putc(com_port, c); + if ( c == '\n' ) serial_putc(com_port, '\r'); +#endif /* serial console */ + + if ( c == '\n' ) { + x = 0; + if ( ++y >= lines ) { + scroll(); + y--; + } + } else if (c == '\b') { + if (x > 0) { + x--; + } + } else { + vidmem [ ( x + cols * y ) * 2 ] = c; + if ( ++x >= cols ) { + x = 0; + if ( ++y >= lines ) { + scroll(); + y--; + } + } + } + } + + cursor(x, y); + + orig_x = x; + orig_y = y; +} + +void error(char *x) +{ + puts("\n\n"); + puts(x); + puts("\n\n -- System halted"); + + while(1); /* Halt */ +} + +static void *zalloc(unsigned size) +{ + void *p = avail_ram; + + size = (size + 7) & -8; + avail_ram += size; + if (avail_ram > end_avail) { + puts("oops... out of memory\n"); + pause(); + } + return p; +} + +#define HEAD_CRC 2 +#define EXTRA_FIELD 4 +#define ORIG_NAME 8 +#define COMMENT 0x10 +#define RESERVED 0xe0 + +void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) +{ + z_stream s; + int r, i, flags; + + /* skip header */ + i = 10; + flags = src[3]; + if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) { + puts("bad gzipped data\n"); + exit(); + } + if ((flags & EXTRA_FIELD) != 0) + i = 12 + src[10] + (src[11] << |