diff options
Diffstat (limited to 'arch')
39 files changed, 1277 insertions, 1080 deletions
diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile index 21d300d12121..90b0a5be2b5f 100644 --- a/arch/ppc/boot/Makefile +++ b/arch/ppc/boot/Makefile @@ -28,7 +28,7 @@ images/vmlinux.gz: $(TOPDIR)/vmlinux # Subdirs and tools needed for each. Assume we always need to go into # 'simple' unless told otherwise. subdir-y := lib common simple -subdir-$(CONFIG_ALL_PPC) := chrp pmac prep +subdir-$(CONFIG_ALL_PPC) := openfirmware prep tools-$(CONFIG_ALL_PPC) := addnote mknote hack-coff mkprep tools-$(CONFIG_PPLUS) := mkbugboot mkprep tools-$(CONFIG_4xx) := mktree @@ -47,6 +47,9 @@ NONBOOT := lib common # These are the subdirs we want to use BOOTDIRS = $(filter-out $(NONBOOT), $(subdir-y)) +makeof1275: + $(MAKE) -C of1275 + # This will make the tools we need. We do it like this to ensure that we use # HOSTCC. -- Tom maketools: @@ -55,7 +58,7 @@ maketools: # The targets all boards support for boot images. BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd -$(BOOT_TARGETS): vmapus lib/zlib.a images/vmlinux.gz maketools +$(BOOT_TARGETS): vmapus lib/zlib.a images/vmlinux.gz makeof1275 maketools ifneq ($(BOOTDIRS),) for d in $(BOOTDIRS); do $(MAKE) -C $$d $@; done endif @@ -80,5 +83,6 @@ vmlinux.sm: $(TOPDIR)/vmlinux utils/addSystemMap clean: $(MAKE) -C images clean $(MAKE) -C utils clean + $(MAKE) -C openfirmware clean include $(TOPDIR)/Rules.make diff --git a/arch/ppc/boot/chrp/Makefile b/arch/ppc/boot/chrp/Makefile deleted file mode 100644 index 5df1db921bf8..000000000000 --- a/arch/ppc/boot/chrp/Makefile +++ /dev/null @@ -1,67 +0,0 @@ -# Makefile for making ELF bootable images for booting on CHRP -# using Open Firmware. -# -# Geert Uytterhoeven September 1997 -# -# Based on coffboot by Paul Mackerras - -LD_ARGS = -T ../ld.script -Ttext 0x00400000 - -OBJS = ../common/crt0.o start.o main.o misc.o ../common/string.o image.o \ - ../common/ofcommon.o - -EXTRA_TARGETS := $(OBJS) -LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a - -# Utils -ADDNOTE = ../utils/addnote -PIGGYBACK = ../utils/piggyback - -ifeq ($(CONFIG_PPC64BRIDGE),y) -END += .64 -AFLAGS += -Wa,-mppc64bridge -endif -ifeq ($(CONFIG_SMP),y) -END += .smp -endif - -TFTPIMAGE=/tftpboot/zImage.chrp$(END) - -all: zImage - -znetboot: zImage - cp -f $(TOPDIR)/vmlinux /tftpboot/vmlinux$(END) - cp ../images/zImage.chrp $(TFTPIMAGE) - -znetboot.initrd: zImage.initrd - cp ../images/zImage.initrd.chrp $(TFTPIMAGE) - -floppy: zImage - mcopy zImage a:zImage - -image.o: ../images/vmlinux.gz ../common/dummy.o - $(OBJCOPY) ../common/dummy.o $@ \ - --add-section=.image=../images/vmlinux.gz \ - --set-section-flags=.image=contents,alloc,load,readonly,data -ifdef CONFIG_XMON - $(OBJCOPY) $@ $@ \ - --add-section=.sysmap=$(TOPDIR)/System.map \ - --set-section-flags=.sysmap=contents,alloc,load,readonly,data -endif - -zImage: $(OBJS) $(LIBS) $(ADDNOTE) - $(LD) $(LD_ARGS) -o ../images/$@.chrp $(OBJS) $(LIBS) - $(OBJCOPY) ../images/$@.chrp ../images/$@.chrp -R .comment -R .ramdisk - cp ../images/$@.chrp ../images/$@.chrp-rs6k - $(ADDNOTE) ../images/$@.chrp-rs6k - -zImage.initrd: $(OBJS) $(LIBS) $(ADDNOTE) ../images/ramdisk.image.gz - $(OBJCOPY) image.o image.o \ - --add-section=.ramdisk=../images/ramdisk.image.gz \ - --set-section-flags=.ramdisk=contents,alloc,load,readonly,data - $(LD) $(LD_ARGS) -o ../images/$@.chrp $(OBJS) $(LIBS) - $(OBJCOPY) ../images/$@.chrp ../images/$@.chrp -R .comment - cp ../images/$@.chrp ../images/$@.chrp-rs6k - $(ADDNOTE) ../images/$@.chrp-rs6k - -include $(TOPDIR)/Rules.make diff --git a/arch/ppc/boot/chrp/misc.S b/arch/ppc/boot/chrp/misc.S deleted file mode 100644 index b2094b9d3df4..000000000000 --- a/arch/ppc/boot/chrp/misc.S +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) Paul Mackerras 1997. - * - * 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. - */ - .text - -/* - * Use the BAT0 registers to map the 1st 8MB of RAM to 0x90000000. - */ - .globl setup_bats -setup_bats: - mfpvr 3 - rlwinm 3,3,16,16,31 /* r3 = 1 for 601, 4 for 604 */ - cmpi 0,3,1 - lis 4,0x9000 - bne 4f - ori 4,4,4 /* set up BAT registers for 601 */ - li 5,0x7f - b 5f -4: ori 4,4,0xff /* set up BAT registers for 604 */ - li 5,2 - mtdbatu 3,4 - mtdbatl 3,5 -5: mtibatu 3,4 - mtibatl 3,5 - isync - blr - -/* - * Flush the dcache and invalidate the icache for a range of addresses. - * - * flush_cache(addr, len) - */ - .global flush_cache -flush_cache: - addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */ - rlwinm. 4,4,27,5,31 - mtctr 4 - beqlr -1: dcbf 0,3 - icbi 0,3 - addi 3,3,0x20 - bdnz 1b - sync - isync - blr diff --git a/arch/ppc/boot/chrp/start.c b/arch/ppc/boot/chrp/start.c deleted file mode 100644 index 69e82819da50..000000000000 --- a/arch/ppc/boot/chrp/start.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (C) Paul Mackerras 1997. - * - * 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 <stdarg.h> - -int (*prom)(void *args); - -void *chosen_handle; -void *stdin; -void *stdout; -void *stderr; - -void exit(void); -void *finddevice(const char *name); -int getprop(void *phandle, const char *name, void *buf, int buflen); - -void printk(char *fmt, ...); - -extern void chrpboot(int a1, int a2, void *prom); -extern int strlen(const char *s); - -void -start(int a1, int a2, void *promptr) -{ - prom = promptr; - chosen_handle = finddevice("/chosen"); - if (chosen_handle == (void *) -1) - exit(); - if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4) - exit(); - stderr = stdout; - if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) - exit(); - - chrpboot(a1, a2, promptr); - for (;;) - exit(); -} - -int -write(void *handle, void *ptr, int nb) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *ihandle; - void *addr; - int len; - int actual; - } args; - - args.service = "write"; - args.nargs = 3; - args.nret = 1; - args.ihandle = handle; - args.addr = ptr; - args.len = nb; - args.actual = -1; - prom(&args); - return args.actual; -} - -int -read(void *handle, void *ptr, int nb) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *ihandle; - void *addr; - int len; - int actual; - } args; - - args.service = "read"; - args.nargs = 3; - args.nret = 1; - args.ihandle = handle; - args.addr = ptr; - args.len = nb; - args.actual = -1; - (*prom)(&args); - return args.actual; -} - -void -exit(void) -{ - struct prom_args { - char *service; - } args; - - for (;;) { - args.service = "exit"; - (*prom)(&args); - } -} - -void -pause(void) -{ - struct prom_args { - char *service; - } args; - - args.service = "enter"; - (*prom)(&args); -} - -void * -finddevice(const char *name) -{ - struct prom_args { - char *service; - int nargs; - int nret; - const char *devspec; - void *phandle; - } args; - - args.service = "finddevice"; - args.nargs = 1; - args.nret = 1; - args.devspec = name; - args.phandle = (void *) -1; - (*prom)(&args); - return args.phandle; -} - -void * -claim(unsigned int virt, unsigned int size, unsigned int align) -{ - struct prom_args { - char *service; - int nargs; - int nret; - unsigned int virt; - unsigned int size; - unsigned int align; - void *ret; - } args; - - args.service = "claim"; - args.nargs = 3; - args.nret = 1; - args.virt = virt; - args.size = size; - args.align = align; - (*prom)(&args); - return args.ret; -} - -int -getprop(void *phandle, const char *name, void *buf, int buflen) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *phandle; - const char *name; - void *buf; - int buflen; - int size; - } args; - - args.service = "getprop"; - args.nargs = 4; - args.nret = 1; - args.phandle = phandle; - args.name = name; - args.buf = buf; - args.buflen = buflen; - args.size = -1; - (*prom)(&args); - return args.size; -} - -int -putc(int c, void *f) -{ - char ch = c; - - if (c == '\n') - putc('\r', f); - return write(f, &ch, 1) == 1? c: -1; -} - -int -putchar(int c) -{ - return putc(c, stdout); -} - -int -fputs(char *str, void *f) -{ - int n = strlen(str); - - return write(f, str, n) == n? 0: -1; -} - -int -readchar(void) -{ - char ch; - - for (;;) { - switch (read(stdin, &ch, 1)) { - case 1: - return ch; - case -1: - printk("read(stdin) returned -1\r\n"); - return -1; - } - } -} - -static char line[256]; -static char *lineptr; -static int lineleft; - -int -getchar(void) -{ - int c; - - if (lineleft == 0) { - lineptr = line; - for (;;) { - c = readchar(); - if (c == -1 || c == 4) - break; - if (c == '\r' || c == '\n') { - *lineptr++ = '\n'; - putchar('\n'); - break; - } - switch (c) { - case 0177: - case '\b': - if (lineptr > line) { - putchar('\b'); - putchar(' '); - putchar('\b'); - --lineptr; - } - break; - case 'U' & 0x1F: - while (lineptr > line) { - putchar('\b'); - putchar(' '); - putchar('\b'); - --lineptr; - } - break; - default: - if (lineptr >= &line[sizeof(line) - 1]) - putchar('\a'); - else { - putchar(c); - *lineptr++ = c; - } - } - } - lineleft = lineptr - line; - lineptr = line; - } - if (lineleft == 0) - return -1; - --lineleft; - return *lineptr++; -} - -extern int vsprintf(char *buf, const char *fmt, va_list args); -static char sprint_buf[1024]; - -void -printk(char *fmt, ...) -{ - va_list args; - int n; - - va_start(args, fmt); - n = vsprintf(sprint_buf, fmt, args); - va_end(args); - write(stdout, sprint_buf, n); -} - -int -printf(char *fmt, ...) -{ - va_list args; - int n; - - va_start(args, fmt); - n = vsprintf(sprint_buf, fmt, args); - va_end(args); - write(stdout, sprint_buf, n); - return n; -} diff --git a/arch/ppc/boot/common/cpc700_memory.c b/arch/ppc/boot/common/cpc700_memory.c new file mode 100644 index 000000000000..c129d53ca42f --- /dev/null +++ b/arch/ppc/boot/common/cpc700_memory.c @@ -0,0 +1,38 @@ +/* + * arch/ppc/boot/common/cpc700_memory.c + * + * Find memory based upon settings in the CPC700 bridge + * + * Author: Dan Cox + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * 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 <asm/types.h> +#include <asm/io.h> +#include "cpc700.h" + +unsigned long +cpc700_get_mem_size(void) +{ + int i; + unsigned long len, amt; + + /* Start at MB1EA, since MB0EA will most likely be the ending address + for ROM space. */ + for(len = 0, i = CPC700_MB1EA; i <= CPC700_MB4EA; i+=4) { + amt = cpc700_read_memreg(i); + if (amt == 0) + break; + len = amt; + } + + return len; +} + + diff --git a/arch/ppc/boot/common/misc-simple.c b/arch/ppc/boot/common/misc-simple.c index 9dbbc83af42d..74693dc19a0a 100644 --- a/arch/ppc/boot/common/misc-simple.c +++ b/arch/ppc/boot/common/misc-simple.c @@ -64,6 +64,7 @@ extern char _end[]; extern unsigned long start; extern int CRT_tstc(void); +extern unsigned long get_mem_size(void); extern unsigned long serial_init(int chan, void *ignored); extern void serial_close(unsigned long com_port); extern void gunzip(void *, int, unsigned char *, int *); @@ -75,10 +76,19 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum) int timer = 0; char *cp, ch; struct bi_record *rec, *birecs; + unsigned long TotalMemory = 0; serial_fixups(); com_port = serial_init(0, NULL); +#if defined(CONFIG_LOPEC) || defined(CONFIG_PAL4) + /* + * Call get_mem_size(), which is memory controller dependant, + * and we must have the correct file linked in here. + */ + TotalMemory = get_mem_size(); +#endif + /* assume the chunk below 8M is free */ end_avail = (char *)0x00800000; @@ -194,6 +204,13 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum) rec->size = sizeof(struct bi_record); rec = (struct bi_record *)((unsigned long)rec + rec->size); + if ( TotalMemory ) { + rec->tag = BI_MEMSIZE; + rec->data[0] = TotalMemory; + rec->size = sizeof(struct bi_record) + sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + } + rec->tag = BI_CMD_LINE; memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1); rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1; diff --git a/arch/ppc/boot/common/mpc10x_memory.c b/arch/ppc/boot/common/mpc10x_memory.c new file mode 100644 index 000000000000..546d0ac75a24 --- /dev/null +++ b/arch/ppc/boot/common/mpc10x_memory.c @@ -0,0 +1,109 @@ +/* + * arch/ppc/boot/common/mpc10x_common.c + * + * A routine to find out how much memory the machine has. + * + * Based on: + * arch/ppc/kernel/mpc10x_common.c + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * 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/pci.h> +#include <asm/types.h> +#include <asm/io.h> +#include "mpc10x.h" + +/* + * *** WARNING - A BAT MUST be set to access the PCI config addr/data regs *** + */ + +/* + * PCI config space macros, similar to indirect_xxx and early_xxx macros. + * We assume bus 0. + */ +#define MPC10X_CFG_read(val, addr, type, op) *val = op((type)(addr)) +#define MPC10X_CFG_write(val, addr, type, op) op((type *)(addr), (val)) + +#define MPC10X_PCI_OP(rw, size, type, op, mask) \ +static void \ +mpc10x_##rw##_config_##size(unsigned int *cfg_addr, \ + unsigned int *cfg_data, int devfn, int offset, \ + type val) \ +{ \ + out_be32(cfg_addr, \ + ((offset & 0xfc) << 24) | (devfn << 16) \ + | (0 << 8) | 0x80); \ + MPC10X_CFG_##rw(val, cfg_data + (offset & mask), type, op); \ + return; \ +} + +MPC10X_PCI_OP(read, byte, u8 *, in_8, 3) +MPC10X_PCI_OP(read, dword, u32 *, in_le32, 0) + +/* + * Read the memory controller registers to determine the amount of memory in + * the system. This assumes that the firmware has correctly set up the memory + * controller registers. On CONFIG_ALL_PPC, we know we are being called + * under a PReP memory map. On all other machines, we assume we are under + * a CHRP memory map. + */ +unsigned long +get_mem_size(void) +{ + unsigned int *config_addr, *config_data, val; + unsigned long start, end, total, offset; + int i; + unsigned char bank_enables; + +#ifdef CONFIG_ALL_PPC + config_addr = (unsigned int *)MPC10X_MAPA_CNFG_ADDR; + config_data = (unsigned int *)MPC10X_MAPA_CNFG_DATA; +#else + config_addr = (unsigned int *)MPC10X_MAPB_CNFG_ADDR; + config_data = (unsigned int *)MPC10X_MAPB_CNFG_DATA; +#endif + + mpc10x_read_config_byte(config_addr, config_data, PCI_DEVFN(0,0), + MPC10X_MCTLR_MEM_BANK_ENABLES, &bank_enables); + + total = 0; + + for (i = 0; i < 8; i++) { + if (bank_enables & (1 << i)) { + offset = MPC10X_MCTLR_MEM_START_1 + ((i > 3) ? 4 : 0); + mpc10x_read_config_dword(config_addr, config_data, + PCI_DEVFN(0,0), offset, &val); + start = (val >> ((i & 3) << 3)) & 0xff; + + offset = MPC10X_MCTLR_EXT_MEM_START_1 + ((i>3) ? 4 : 0); + mpc10x_read_config_dword(config_addr, config_data, + PCI_DEVFN(0,0), offset, &val); + val = (val >> ((i & 3) << 3)) & 0x03; + start = (val << 28) | (start << 20); + + offset = MPC10X_MCTLR_MEM_END_1 + ((i > 3) ? 4 : 0); + mpc10x_read_config_dword(config_addr, config_data, + PCI_DEVFN(0,0), offset, &val); + end = (val >> ((i & 3) << 3)) & 0xff; + + offset = MPC10X_MCTLR_EXT_MEM_END_1 + ((i > 3) ? 4 : 0); + mpc10x_read_config_dword(config_addr, config_data, + PCI_DEVFN(0,0), offset, &val); + val = (val >> ((i & 3) << 3)) & 0x03; + end = (val << 28) | (end << 20) | 0xfffff; + + total += (end - start + 1); + } + } + + return total; +} diff --git a/arch/ppc/boot/common/util.S b/arch/ppc/boot/common/util.S index 206d7f0d6e40..cc3f83a598a8 100644 --- a/arch/ppc/boot/common/util.S +++ b/arch/ppc/boot/common/util.S @@ -160,11 +160,6 @@ udelay: blt 2b 3: blr -.globl _put_MSR -_put_MSR: - mtmsr r3 - blr - .section ".relocate_code","xa" /* * Flush and enable instruction cache diff --git a/arch/ppc/boot/include/cpc700.h b/arch/ppc/boot/include/cpc700.h new file mode 100644 index 000000000000..28cfcde44909 --- /dev/null +++ b/arch/ppc/boot/include/cpc700.h @@ -0,0 +1,26 @@ + +#ifndef __PPC_BOOT_CPC700_H +#define __PPC_BOOT_CPC700_H + +#define CPC700_MEM_CFGADDR 0xff500008 +#define CPC700_MEM_CFGDATA 0xff50000c + +#define CPC700_MB0SA 0x38 +#define CPC700_MB0EA 0x58 +#define CPC700_MB1SA 0x3c +#define CPC700_MB1EA 0x5c +#define CPC700_MB2SA 0x40 +#define CPC700_MB2EA 0x60 +#define CPC700_MB3SA 0x44 +#define CPC700_MB3EA 0x64 +#define CPC700_MB4SA 0x48 +#define CPC700_MB4EA 0x68 + +static inline long +cpc700_read_memreg(int reg) +{ + out_be32((volatile unsigned int *) CPC700_MEM_CFGADDR, reg); + return in_be32((volatile unsigned int *) CPC700_MEM_CFGDATA); +} + +#endif diff --git a/arch/ppc/boot/include/mpc10x.h b/arch/ppc/boot/include/mpc10x.h new file mode 100644 index 000000000000..e71b667a683e --- /dev/null +++ b/arch/ppc/boot/include/mpc10x.h @@ -0,0 +1,67 @@ +/* + * arch/ppc/boot/include/mpc10.h + * + * Common defines for the Motorola SPS MPC106/8240/107 Host bridge/Mem + * ctrl/EPIC/etc. + * + * Author: Tom Rini <trini@mvista.com> + * + * This is a heavily stripped down version of: + * include/asm-ppc/mpc10x.h + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * 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. + */ +#ifndef __BOOT_MPC10X_H__ +#define __BOOT_MPC10X_H__ + +/* + * The values here don't completely map everything but should work in most + * cases. + * + * MAP A (PReP Map) + * Processor: 0x80000000 - 0x807fffff -> PCI I/O: 0x00000000 - 0x007fffff + * Processor: 0xc0000000 - 0xdfffffff -> PCI MEM: 0x00000000 - 0x1fffffff + * PCI MEM: 0x80000000 -> Processor System Memory: 0x00000000 + * EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB) + * + * MAP B (CHRP Map) + * Processor: 0xfe000000 - 0xfebfffff -> PCI I/O: 0x00000000 - 0x00bfffff + * Processor: 0x80000000 - 0xbfffffff -> PCI MEM: 0x80000000 - 0xbfffffff + * PCI MEM: 0x00000000 -> Processor System Memory: 0x00000000 + * EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB) + */ + +/* Define the type of map to use */ +#define MPC10X_MEM_MAP_A 1 +#define MPC10X_MEM_MAP_B 2 + +/* Map A (PReP Map) Defines */ +#define MPC10X_MAPA_CNFG_ADDR 0x80000cf8 +#define MPC10X_MAPA_CNFG_DATA 0x80000cfc + +/* Map B (CHRP Map) Defines */ +#define MPC10X_MAPB_CNFG_ADDR 0xfec00000 +#define MPC10X_MAPB_CNFG_DATA 0xfee00000 + +/* Define offsets for the memory controller registers in the config space */ +#define MPC10X_MCTLR_MEM_START_1 0x80 /* Banks 0-3 */ +#define MPC10X_MCTLR_MEM_START_2 0x84 /* Banks 4-7 */ +#define MPC10X_MCTLR_EXT_MEM_START_1 0x88 /* Banks 0-3 */ +#define MPC10X_MCTLR_EXT_MEM_START_2 0x8c /* Banks 4-7 */ + +#define MPC10X_MCTLR_MEM_END_1 0x90 /* Banks 0-3 */ +#define MPC10X_MCTLR_MEM_END_2i 0x94 /* Banks 4-7 */ +#define MPC10X_MCTLR_EXT_MEM_END_1 0x98 /* Banks 0-3 */ +#define MPC10X_MCTLR_EXT_MEM_END_2 0x9c /* Banks 4-7 */ + +#define MPC10X_MCTLR_MEM_BANK_ENABLES 0xa0 + +#endif /* __BOOT_MPC10X_H__ */ diff --git a/arch/ppc/boot/include/of1275.h b/arch/ppc/boot/include/of1275.h new file mode 100644 index 000000000000..6cd07e5f5653 --- /dev/null +++ b/arch/ppc/boot/include/of1275.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * 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. + */ + +typedef void *prom_handle; +typedef void *ihandle; +typedef void *phandle; +typedef int (*prom_entry)(void *); + +#define OF_INVALID_HANDLE ((prom_handle)-1UL) + +extern prom_entry of_prom_entry; + +/* function declarations */ + +void * claim(unsigned int virt, unsigned int size, unsigned int align); +void enter(void); +void exit(void); +phandle finddevice(const char *name); +int getprop(phandle node, const char *name, void *buf, int buflen); +void ofinit(prom_entry entry); +int ofstdio(ihandle *stdin, ihandle *stdout, ihandle *stderr); +int read(ihandle instance, void *buf, int buflen); +void release(void *virt, unsigned int size); +int write(ihandle instance, void *buf, int buflen); + +/* inlines */ + +extern inline void pause(void) +{ + enter(); +} diff --git a/arch/ppc/boot/ld.script b/arch/ppc/boot/ld.script index 9d4de80f8ba3..742469efe775 100644 --- a/arch/ppc/boot/ld.script +++ b/arch/ppc/boot/ld.script @@ -39,7 +39,7 @@ SECTIONS PROVIDE (etext = .); /* Read-write section, merged into data segment: */ - . = (. + 0x0FFF) & 0xFFFFF000; + . = ALIGN(8); .data : { *(.data) @@ -69,6 +69,7 @@ SECTIONS _edata = .; PROVIDE (edata = .); + . = ALIGN(8); __bss_start = .; .bss : { diff --git a/arch/ppc/boot/of1275/Makefile b/arch/ppc/boot/of1275/Makefile new file mode 100644 index 000000000000..e855cb64b28f --- /dev/null +++ b/arch/ppc/boot/of1275/Makefile @@ -0,0 +1,10 @@ +# +# Makefile of1275 stuff +# + +L_TARGET := of1275.a + +obj-y := claim.o enter.o exit.o finddevice.o getprop.o ofinit.o \ + ofstdio.o read.o release.o write.o + +include $(TOPDIR)/Rules.make diff --git a/arch/ppc/boot/of1275/claim.c b/arch/ppc/boot/of1275/claim.c new file mode 100644 index 000000000000..e060292ae2a7 --- /dev/null +++ b/arch/ppc/boot/of1275/claim.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * 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 "of1275.h" + +void * +claim(unsigned int virt, unsigned int size, unsigned int align) +{ + struct prom_args { + char *service; + int nargs; + int nret; + unsigned int virt; + unsigned int size; + unsigned int align; + void *ret; + } args; + + args.service = "claim"; + args.nargs = 3; + args.nret = 1; + args.virt = virt; + args.size = size; + args.align = align; + (*of_prom_entry)(&args); + return args.ret; +} diff --git a/arch/ppc/boot/of1275/enter.c b/arch/ppc/boot/of1275/enter.c new file mode 100644 index 000000000000..abe87a8fe2db --- /dev/null +++ b/arch/ppc/boot/of1275/enter.c @@ -0,0 +1,22 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * 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 "of1275.h" + +void +enter(void) +{ + struct prom_args { + char *service; + } args; + + args.service = "enter"; + (*of_prom_entry)(&args); +} diff --git a/arch/ppc/boot/of1275/exit.c b/arch/ppc/boot/of1275/exit.c new file mode 100644 index 000000000000..b9f89b6a8b45 --- /dev/null +++ b/arch/ppc/boot/of1275/exit.c @@ -0,0 +1,24 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * 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 "of1275.h" + +void +exit(void) +{ + struct prom_args { + char *service; + } args; + + for (;;) { + args.service = "exit"; + (*of_prom_entry)(&args); + } +} diff --git a/arch/ppc/boot/of1275/finddevice.c b/arch/ppc/boot/of1275/finddevice.c new file mode 100644 index 000000000000..2c0f7cbb793e --- /dev/null +++ b/arch/ppc/boot/of1275/finddevice.c @@ -0,0 +1,31 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * 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 "of1275.h" + +phandle +finddevice(const char *name) +{ + struct prom_args { + char *service; + int nargs; + int nret; + const char *devspec; + phandle device; + } args; + + args.service = "finddevice"; + args.nargs = 1; + args.nret = 1; + args.devspec = name; + args.device = OF_INVALID_HANDLE; + (*of_prom_entry)(&args); + return args.device; +} diff --git a/arch/ppc/boot/of1275/getprop.c b/arch/ppc/boot/of1275/getprop.c new file mode 100644 index 000000000000..0cf75f035e4e --- /dev/null +++ b/arch/ppc/boot/of1275/getprop.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * 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 "of1275.h" + +int +getprop(phandle node, const char *name, void *buf, int buflen) +{ + struct prom_args { + char *service; + int nargs; + int nret; + phandle node; + const char *name; + void *buf; + int buflen; + int size; + } args; + + args.service = "getprop"; + args.nargs = 4; + args.nret = 1; + args.node = node; + args.name = name; + args.buf = buf; + args.buflen = buflen; + args.size = -1; + (*of_prom_entry)(&args); + return args.size; +} diff --git a/arch/ppc/boot/of1275/ofinit.c b/arch/ppc/boot/of1275/ofinit.c new file mode 100644 index 000000000000..44950df716a9 --- /dev/null +++ b/arch/ppc/boot/of1275/ofinit.c @@ -0,0 +1,19 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * 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 "of1275.h" + +prom_entry of_prom_entry; + +void +ofinit(prom_entry prom_ptr) +{ + of_prom_entry = prom_ptr; +} diff --git a/arch/ppc/boot/of1275/ofstdio.c b/arch/ppc/boot/of1275/ofstdio.c new file mode 100644 index 000000000000..354036358bff --- /dev/null +++ b/arch/ppc/boot/of1275/ofstdio.c @@ -0,0 +1,32 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * 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 "of1275.h" + +int +ofstdio(ihandle *stdin, ihandle *stdout, ihandle *stderr) +{ + ihandle in, out; + phandle chosen; + + if ((chosen = finddevice("/chosen")) == OF_INVALID_HANDLE) + goto err; + if (getprop(chosen, "stdout", &out, sizeof(out)) != 4) + goto err; + if (getprop(chosen, "stdin", &in, sizeof(in)) != 4) + goto err; + + *stdin = in; + *stdout = out; + *stderr = out; + return 0; +err: + return -1; +} diff --git a/arch/ppc/boot/of1275/read.c b/arch/ppc/boot/of1275/read.c new file mode 100644 index 000000000000..122813649fce --- /dev/null +++ b/arch/ppc/boot/of1275/read.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * 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 "of1275.h" + +int +read(ihandle instance, void *buf, int buflen) +{ + struct prom_args { + char *service; + int nargs; + int nret; + ihandle instance; + void *buf; + int buflen; + int actual; + } args; + + args.service = "read"; + args.nargs = 3; + args.nret = 1; + args.instance = instance; + args.buf = buf; + args.buflen = buflen; + args.actual = -1; + (*of_prom_entry)(&args); + return args.actual; +} diff --git a/arch/ppc/boot/of1275/release.c b/arch/ppc/boot/of1275/release.c new file mode 100644 index 000000000000..28032d37145d --- /dev/null +++ b/arch/ppc/boot/of1275/release.c @@ -0,0 +1,30 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * 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 "of1275.h" + +void +release(void *virt, unsigned int size) +{ + struct prom_args { + char *service; + int nargs; + int nret; + void *virt; + unsigned int size; + } args; + + args.service = "release"; + args.nargs = 2; + args.nret = 0; + args.virt = virt; + args.size = size; + (*of_prom_entry)(&args); +} diff --git a/arch/ppc/boot/of1275/write.c b/arch/ppc/boot/of1275/write.c new file mode 100644 index 000000000000..7361b9b2fca5 --- /dev/null +++ b/arch/ppc/boot/of1275/write.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * Copyright (C) Leigh Brown 2002. + * + * 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 "of1275.h" + +int +write(ihandle instance, void *buf, int buflen) +{ + struct prom_args { + char *service; + int nargs; + int nret; + ihandle instance; + void *buf; + int buflen; + int actual; + } args; + + args.service = "write"; + args.nargs = 3; + args.nret = 1; + args.instance = instance; + args.buf = buf; + args.buflen = buflen; + args.actual = -1; + (*of_prom_entry)(&args); + return args.actual; +} diff --git a/arch/ppc/boot/openfirmware/Makefile b/arch/ppc/boot/openfirmware/Makefile new file mode 100644 index 000000000000..51329368dd61 --- /dev/null +++ b/arch/ppc/boot/openfirmware/Makefile @@ -0,0 +1,137 @@ +# Makefile for making bootable images on various OpenFirmware machines. +# +# Paul Mackerras January 1997 +# XCOFF bootable images for PowerMacs +# Geert Uytterhoeven September 1997 +# ELF bootable iamges for CHRP machines. +# Tom Rini January 2001 +# Cleaned up, moved into arch/ppc/boot/pmac +# Tom Rini July/August 2002 +# Merged 'chrp' and 'pmac' into 'openfirmware', and cleaned up the +# rules. + +OBJCOPY_ARGS = -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment +COFF_LD_ARGS = -T ../ld.script -e _start -Ttext 0x00500000 -Bstatic +CHRP_LD_ARGS = -T ../ld.script -e _start -Ttext 0x00400000 +NEWWORLD_LD_ARGS = -T ../ld.script -e _start -Ttext 0x01000000 + +COMMONOBJS = start.o misc.o ../common/string.o common.o +COFFOBJS = ../common/coffcrt0.o $(COMMONOBJS) coffmain.o +CHRPOBJS = ../common/crt0.o $(COMMONOBJS) chrpmain.o +NEWWORLDOBJS = ../common/crt0.o $(COMMONOBJS) newworldmain.o + +EXTRA_TARGETS := $(COFFOBJS) $(CHRPOBJS) $(NEWWORLDOBJS) +LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a ../of1275/of1275.a + +ADDNOTE := ../utils/addnote +MKNOTE := ../utils/mknote +SIZE := ../utils/size +OFFSET := ../utils/offset +HACKCOFF := ../utils/hack-coff + +ifdef CONFIG_SMP +END := .smp +endif +ifdef CONFIG_PPC64BRIDGE +END += .64 +endif + +TFTPIMAGE=/tftpboot/zImage. + +../common/coffcrt0.o: + $(MAKE) -C ../common coffcrt0.o + +image.o: ../images/vmlinux.gz ../common/dummy.o + $(OBJCOPY) ../common/dummy.o $@ -R .comment \ + --add-section=.image=../images/vmlinux.gz \ + --set-section-flags=.image=contents,alloc,load,readonly,data +ifdef CONFIG_XMON + $(OBJCOPY) $@ $@ \ + --add-section=.sysmap=$(TOPDIR)/System.map \ + --set-section-flags=.sysmap=contents,alloc,load,readonly,data +endif + +# Place the ramdisk in the initrd image. +image-initrd.o: image.o ../images/ramdisk.image.gz + $(OBJCOPY) image.o $@ \ + --add-section=.ramdisk=../images/ramdisk.image.gz \ + --set-section-flags=.ramdisk=contents,alloc,load,readonly,data + +# Create the note section for New-World PowerMacs. +note: $(MKNOTE) + $(MKNOTE) > note + +znetboot: vmlinux.coff vmlinux.elf-pmac zImage + cp ../images/vmlinux.coff $(TFTPIMAGE).pmac$(END) + cp ../images/vmlinux.elf-pmac $(TFTPIMAGE).pmac$(END)elf + cp ../images/zImage.chrp $(TFTPIMAGE).chrp$(END) + +znetboot.initrd: vmlinux.initrd.coff vmlinux.initrd.elf-pmac + cp ../images/vmlinux.initrd.coff $(TFTPIMAGE).pmac$(END) + cp ../images/vmlinux.initrd.elf-pmac $(TFTPIMAGE).pmac$(END).elf + cp ../images/zImage.initrd.chrp $(TFTPIMAGE).chrp$(END) + +miboot.image: ../common/dummy.o ../images/vmlinux.gz + $(OBJCOPY) $(OBJCOPY_ARGS) --add-section=image=../images/vmlinux.gz \ + ../common/dummy.o ../images/$@ + +miboot.initrd.image: miboot.image ../images/ramdisk.image.gz + $(OBJCOPY) $(OBJCOPY_ARGS) \ + --add-section=initrd=../images/ramdisk.image.gz \ + ../images/miboot.image ../images/$@ + +coffboot: $(COFFOBJS) image.o $(LIBS) + $(LD) -o $@ $(COFF_LD_ARGS) $^ + $(OBJCOPY) $@ $@ -R .comment -R .ramdisk + +coffboot.initrd: $(COFFOBJS) image-initrd.o $(LIBS) + $(LD) -o $@ $(COFF_LD_ARGS) $^ + $(OBJCOPY) $@ $@ -R .comment + +vmlinux.coff: coffboot $(HACKCOFF) + $(OBJCOPY) $(OBJCOPY_ARGS) coffboot ../images/$@ + $(HACKCOFF) ../images/$@ + rm -f coffboot + ln -sf vmlinux.coff ../images/zImage.pmac + +vmlinux.initrd.coff: coffboot.initrd $(HACKCOFF) + $(OBJCOPY) $(OBJCOPY_ARGS) coffboot.initrd ../images/$@ + $(HACKCOFF) ../images/$@ + rm -f coffboot.initrd + ln -sf vmlinux.initrd.coff ../images/zImage.initrd.pmac + +vmlinux.elf-pmac: $(NEWWORLDOBJS) $(LIBS) image.o + $(LD) $(NEWWORLD_LD_ARGS) -o ../images/$@ $^ + +vmlinux.initrd.elf-pmac: $(NEWWORLDOBJS) $(LIBS) image-initrd.o + $(LD) $(NEWWORLD_LD_ARGS) -o ../images/$@ $^ + +zImage.chrp: $(CHRPOBJS) image.o $(LIBS) + $(LD) $(CHRP_LD_ARGS) -o ../images/$@ $^ + +zImage.initrd.chrp: $(CHRPOBJS) image-initrd.o $(LIBS) + $(LD) $(CHRP_LD_ARGS) -o ../images/$@ $^ + +zImage: vmlinux.coff vmlinux.elf-pmac zImage.chrp miboot.image $(ADDNOTE) \ + note + $(OBJCOPY) ../images/vmlinux.elf-pmac ../images/vmlinux.elf-pmac \ + --add-section=.note=note -R .comment -R .ramdisk + $(OBJCOPY) ../images/zImage.chrp ../images/zImage.chrp \ + -R .comment -R .ramdisk + cp ../images/zImage.chrp ../images/zImage.chrp-rs6k + $(ADDNOTE) ../images/zImage.chrp-rs6k + +zImage.initrd: vmlinux.initrd.coff vmlinux.initrd.elf-pmac zImage.initrd.chrp \ + miboot.initrd.image $(ADDNOTE) note + $(OBJCOPY) ../images/vmlinux.initrd.elf-pmac \ + ../images/vmlinux.initrd.elf-pmac --add-section=.note=note \ + -R .comment + $(OBJCOPY) ../images/zImage.initrd.chrp ../images/zImage.initrd.chrp \ + -R .comment + cp ../images/zImage.initrd.chrp ../images/zImage.initrd.chrp-rs6k + $(ADDNOTE) ../images/zImage.initrd.chrp-rs6k + +clean: + rm -f note + +include $(TOPDIR)/Rules.make diff --git a/arch/ppc/boot/chrp/main.c b/arch/ppc/boot/openfirmware/chrpmain.c index a920ea81afbf..30da57e915d3 100644 --- a/arch/ppc/boot/chrp/main.c +++ b/arch/ppc/boot/openfirmware/chrpmain.c @@ -7,23 +7,20 @@ * 2 of the License, or (at your option) any later version. */ #include "nonstdio.h" +#include "of1275.h" #include <asm/processor.h> #include <asm/page.h> /* Passed from the linker */ extern char __image_begin, __image_end; -extern char __ramdisk_begin[], __ramdisk_end; +extern char __ramdisk_begin, __ramdisk_end; extern char _start, _end; -extern int getprop(void *, const char *, void *, int); extern unsigned int heap_max; -extern void claim(unsigned int virt, unsigned int size, unsigned int align); -extern void *finddevice(const char *); extern void flush_cache(void *, unsigned long); extern void gunzip(void *, int, unsigned char *, int *); extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach, unsigned int progend); -extern void pause(void); char *avail_ram; char *begin_avail, *end_avail; @@ -46,7 +43,7 @@ static char scratch[SCRATCH_SIZE]; /* 1MB of scratch space for gunzip */ typedef void (*kernel_start_t)(int, int, void *, unsigned int, unsigned int); void -chrpboot(int a1, int a2, void *prom) +boot(int a1, int a2, void *prom) { unsigned sa, len; void *dst; @@ -55,23 +52,23 @@ chrpboot(int a1, int a2, void *prom) printf("chrpboot starting: loaded at 0x%p\n\r", &_start); - initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin); + initrd_size = &__ramdisk_end - &__ramdisk_begin; if (initrd_size) { initrd_start = (RAM_END - initrd_size) & ~0xFFF; a1 = initrd_start; a2 = initrd_size; claim(initrd_start, RAM_END - initrd_start, 0); printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r", - initrd_start, (char *)(&__ramdisk_begin), initrd_size); - memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size); + initrd_start, &__ramdisk_begin, initrd_size); + memcpy((char *)initrd_start, &__ramdisk_begin, initrd_size); } else { initrd_start = 0; initrd_size = 0; a2 = 0xdeadbeef; } - im = (char *)(&__image_begin); - len = (char *)(&__image_end) - (char *)(&__image_begin); + im = &__image_begin; + len = &__image_end - &__image_begin; /* claim 4MB starting at PROG_START */ claim(PROG_START, PROG_SIZE - PROG_START, 0); dst = (void *) PROG_START; diff --git a/arch/ppc/boot/pmac/coffmain.c b/arch/ppc/boot/openfirmware/coffmain.c index ee630daaad5f..3aff9feaaae0 100644 --- a/arch/ppc/boot/pmac/coffmain.c +++ b/arch/ppc/boot/openfirmware/coffmain.c @@ -10,6 +10,7 @@ #include <asm/page.h> #include "nonstdio.h" +#include "of1275.h" #include "zlib.h" /* Passed from the linker */ @@ -17,17 +18,13 @@ extern char __image_begin, __image_end; extern char __ramdisk_begin[], __ramdisk_end; extern char _start, _end; -extern char *claim(unsigned, unsigned, unsigned); extern char image_data[], initrd_data[]; extern int initrd_len, image_len; -extern int getprop(void *, const char *, void *, int); extern unsigned int heap_max; -extern void *finddevice(const char *); extern void flush_cache(void *start, unsigned int len); extern void gunzip(void *, int, unsigned char *, int *); extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach, unsigned int progend); -extern void pause(void); extern void setup_bats(unsigned long start); char *avail_ram; diff --git a/arch/ppc/boot/openfirmware/common.c b/arch/ppc/boot/openfirmware/common.c new file mode 100644 index 000000000000..b1e593521654 --- /dev/null +++ b/arch/ppc/boot/openfirmware/common.c @@ -0,0 +1,179 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * + * 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 "zlib.h" +#include "nonstdio.h" +#include "of1275.h" +#include <asm/bootinfo.h> +#include <asm/page.h> + +/* Information from the linker */ +extern char __sysmap_begin, __sysmap_end; + +extern int strcmp(const char *s1, const char *s2); +extern char *avail_ram, *avail_high; +extern char *end_avail; + +unsigned int heap_use, heap_max; + +struct memchunk { + unsigned int size; + struct memchunk *next; +}; + +static struct memchunk *freechunks; + +static void *zalloc(void *x, unsigned items, unsigned size) +{ + void *p; + struct memchunk **mpp, *mp; + + size *= items; + size = (size + 7) & -8; + heap_use += size; + if (heap_use > heap_max) + heap_max = heap_use; + for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) { + if (mp->size == size) { + *mpp = mp->next; + return mp; + } + } + p = avail_ram; + avail_ram += size; + if (avail_ram > avail_high) + avail_high = avail_ram; + if (avail_ram > end_avail) { + printf("oops... out of memory\n\r"); + pause(); + } + return p; +} + +static void zfree(void *x, void *addr, unsigned nb) +{ + struct memchunk *mp = addr; + + nb = (nb + 7) & -8; + heap_use -= nb; + if (avail_ram == addr + nb) { + avail_ram = addr; + return; + } + mp->size = nb; + mp->next = freechunks; + freechunks = mp; +} + +#define HEAD_CRC 2 +#define EXTRA_FIELD 4 +#define ORIG_NAME 8 +#define COMMENT 0x10 +#define RESERVED 0xe0 + +#define DEFLATED 8 + +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] != DEFLATED || (flags & RESERVED) != 0) { + printf("bad gzipped data\n\r"); + exit(); + } + if ((flags & EXTRA_FIELD) != 0) + i = 12 + src[10] + (src[11] << 8); + if ((flags & ORIG_NAME) != 0) + while (src[i++] != 0) + ; + if ((flags & COMMENT) != 0) + while (src[i++] != 0) + ; + if ((flags & HEAD_CRC) != 0) + i += 2; + if (i >= *lenp) { + printf("gunzip: ran out of data in header\n\r"); + exit(); + } + + s.zalloc = zalloc; + s.zfree = zfree; + r = inflateInit2(&s, -MAX_WBITS); + if (r != Z_OK) { + printf("inflateInit2 returned %d\n\r", r); + exit(); + } + s.next_in = src + i; + s.avail_in = *lenp - i; + s.next_out = dst; + s.avail_out = dstlen; + r = inflate(&s, Z_FINISH); + if (r != Z_OK && r != Z_STREAM_END) { + printf("inflate returned %d msg: %s\n\r", r, s.msg); + exit(); + } + *lenp = s.next_out - (unsigned char *) dst; + inflateEnd(&s); +} + +/* Make a bi_rec in OF. We need to be passed a name for BI_BOOTLOADER_ID, + * a machine type for BI_MACHTYPE, and the location where the end of the + * bootloader is (PROG_START + PROG_SIZE) + */ +void make_bi_recs(unsigned long addr, char *name, unsigned int mach, + unsigned long progend) +{ + unsigned long sysmap_size; + struct bi_record *rec; + + /* Figure out the size of a possible System.map we're going to + * pass along. + * */ + sysmap_size = (unsigned long)(&__sysmap_end) - + (unsigned long)(&__sysmap_begin); + + /* leave a 1MB gap then align to the next 1MB boundary */ + addr = _ALIGN(addr+ (1<<20) - 1, (1<<20)); + /* oldworld machine seem very unhappy about this. -- Tom */ + if (addr >= progend) + claim(addr, 0x1000, 0); + + rec = (struct bi_record *)addr; + rec->tag = BI_FIRST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_BOOTLOADER_ID; + sprintf( (char *)rec->data, name); + rec->size = sizeof(struct bi_record) + strlen(name) + 1; + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_MACHTYPE; + rec->data[0] = mach; + rec->data[1] = 1; + rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + if (sysmap_size) { + rec->tag = BI_SYSMAP; + rec->data[0] = (unsigned long)(&__sysmap_begin); + rec->data[1] = sysmap_size; + rec->size = sizeof(struct bi_record) + 2 * + sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + } + + rec->tag = BI_LAST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); +} diff --git a/arch/ppc/boot/pmac/misc.S b/arch/ppc/boot/openfirmware/misc.S index 05639bdd1c24..05639bdd1c24 100644 --- a/arch/ppc/boot/pmac/misc.S +++ b/arch/ppc/boot/openfirmware/misc.S diff --git a/arch/ppc/boot/pmac/chrpmain.c b/arch/ppc/boot/openfirmware/newworldmain.c index b9c5166ed045..1fed5604eec5 100644 --- a/arch/ppc/boot/pmac/chrpmain.c +++ b/arch/ppc/boot/openfirmware/newworldmain.c @@ -7,6 +7,7 @@ * 2 of the License, or (at your option) any later version. */ #include "nonstdio.h" +#include "of1275.h" #include <asm/processor.h> #include <asm/page.h> @@ -15,16 +16,11 @@ extern char __image_begin, __image_end; extern char __ramdisk_begin[], __ramdisk_end; extern char _start, _end; -extern int getprop(void *, const char *, void *, int); extern unsigned int heap_max; -extern void *claim(unsigned int virt, unsigned int size, unsigned int align); -extern void *finddevice(const char *); extern void flush_cache(void *start, unsigned int len); extern void gunzip(void *, int, unsigned char *, int *); extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach, unsigned int progend); -extern void pause(void); -extern void release(void *ptr, unsigned int len); char *avail_ram; char *begin_avail, *end_avail; 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 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * + * 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 <stdarg.h> +#include "of1275.h" + +extern int strlen(const char *s); +extern void boot(int a1, int a2, void *prom); + +phandle stdin; +phandle stdout; +phandle stderr; + +void printk(char *fmt, ...); + +void +start(int a1, int a2, void *promptr) +{ + ofinit(promptr); + if (ofstdio(&stdin, &stdout, &stderr)) + exit(); + + boot(a1, a2, promptr); + for (;;) + exit(); +} + +int writestring(void *f, char *ptr, int nb) +{ + int w = 0, i; + char *ret = "\r"; + + for (i = 0; i < nb; ++i) { + if (ptr[i] == '\n') { + if (i > w) { + write(f, ptr + w, i - w); + w = i; + } + write(f, ret, 1); + } + } + if (w < nb) + write(f, ptr + w, nb - w); + return nb; +} + +int +putc(int c, void *f) +{ + char ch = c; + + return writestring(f, &ch, 1) == 1? c: -1; +} + +int +putchar(int c) +{ + return putc(c, stdout); +} + +int +fputs(char *str, void *f) +{ + int n = strlen(str); + + return writestring(f, str, n) == n? 0: -1; +} + +int +readchar(void) +{ + char ch; + + for (;;) { + switch (read(stdin, &ch, 1)) { + case 1: + return ch; + case -1: + printk("read(stdin) returned -1\n"); + return -1; + } + } +} + +static char line[256]; +static char *lineptr; +static int lineleft; + +int +getchar(void) +{ + int c; + + if (lineleft == 0) { + lineptr = line; + for (;;) { + c = readchar(); + if (c == -1 || c == 4) + break; + if (c == '\r' || c == '\n') { + *lineptr++ = '\n'; + putchar('\n'); + break; + } + switch (c) { + case 0177: + case '\b': + if (lineptr > line) { + putchar('\b'); + putchar(' '); + putchar('\b'); + --lineptr; + } + break; + case 'U' & 0x1F: + while (lineptr > line) { + putchar('\b'); + putchar(' '); + putchar('\b'); + --lineptr; + } + break; + default: + if (lineptr >= &line[sizeof(line) - 1]) + putchar('\a'); + else { + putchar(c); + *lineptr++ = c; + } + } + } + lineleft = lineptr - line; + lineptr = line; + } + if (lineleft == 0) + return -1; + --lineleft; + return *lineptr++; +} + +extern int vsprintf(char *buf, const char *fmt, va_list args); +static char sprint_buf[1024]; + +void +printk(char *fmt, ...) +{ + va_list args; + int n; + + va_start(args, fmt); + n = vsprintf(sprint_buf, fmt, args); + va_end(args); + writestring(stdout, sprint_buf, n); +} + +int +printf(char *fmt, ...) +{ + va_list args; + int n; + + va_start(args, fmt); + n = vsprintf(sprint_buf, fmt, args); + va_end(args); + writestring(stdout, sprint_buf, n); + return n; +} diff --git a/arch/ppc/boot/pmac/Makefile b/arch/ppc/boot/pmac/Makefile deleted file mode 100644 index a401aa9042fb..000000000000 --- a/arch/ppc/boot/pmac/Makefile +++ /dev/null @@ -1,110 +0,0 @@ -# Makefile for making XCOFF bootable images for booting on PowerMacs -# using Open Firmware. -# -# Paul Mackerras January 1997 -# -# Cleaned up, moved into arch/ppc/boot/pmac -# Tom Rini January 2001 - -OBJCOPY_ARGS = -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment -COFF_LD_ARGS = -T ../ld.script -e _start -Ttext 0x00500000 -Bstatic -CHRP_LD_ARGS = -T ../ld.script -Ttext 0x01000000 - -COMMONOBJS = start.o misc.o ../common/string.o ../common/ofcommon.o -COFFOBJS = ../common/coffcrt0.o $(COMMONOBJS) coffmain.o -CHRPOBJS = ../common/crt0.o $(COMMONOBJS) chrpmain.o - -EXTRA_TARGETS := $(COFFOBJS) $(CHRPOBJS) -LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a - -MKNOTE := ../utils/mknote -SIZE := ../utils/size -OFFSET := ../utils/offset -HACKCOFF := ../utils/hack-coff - -ifdef CONFIG_SMP -END := .smp -endif -ifdef CONFIG_PPC64BRIDGE -END += .64 -endif - -TFTPIMAGE=/tftpboot/zImage.pmac$(END) - -../common/coffcrt0.o: - $(MAKE) -C ../common coffcrt0.o - -image.o: ../images/vmlinux.gz ../common/dummy.o - $(OBJCOPY) ../common/dummy.o $@ -R .comment \ - --add-section=.image=../images/vmlinux.gz \ - --set-section-flags=.image=contents,alloc,load,readonly,data -ifdef CONFIG_XMON - $(OBJCOPY) $@ $@ \ - --add-section=.sysmap=$(TOPDIR)/System.map \ - --set-section-flags=.sysmap=contents,alloc,load,readonly,data -endif - -znetboot: vmlinux.coff vmlinux.elf-pmac zImage - cp ../images/vmlinux.coff $(TFTPIMAGE) - cp ../images/vmlinux.elf-pmac $(TFTPIMAGE).elf - -znetboot.initrd: vmlinux.initrd.coff vmlinux.initrd.elf-pmac - cp ../images/vmlinux.initrd.coff $(TFTPIMAGE) - cp ../images/vmlinux.initrd.elf-pmac $(TFTPIMAGE).elf - -miboot.image: ../common/dummy.o ../images/vmlinux.gz - $(OBJCOPY) $(OBJCOPY_ARGS) --add-section=image=../images/vmlinux.gz \ - ../common/dummy.o ../images/$@ - -miboot.initrd.image: miboot.image ../images/ramdisk.image.gz - $(OBJCOPY) $(OBJCOPY_ARGS) --add-section=initrd=../images/ramdisk.image.gz \ - ../images/miboot.image ../images/$@ - -coffboot: $(COFFOBJS) image.o $(LIBS) ../ld.script - $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) image.o $(LIBS) - $(OBJCOPY) $@ $@ -R .comment - -coffboot.initrd: $(COFFOBJS) image.o $(LIBS) ../ld.script \ - ../images/ramdisk.image.gz - $(OBJCOPY) image.o image-coff.o \ - --add-section=.ramdisk=../images/ramdisk.image.gz \ - --set-section-flags=.ramdisk=contents,alloc,load,readonly,data - $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) image-coff.o $(LIBS) - $(OBJCOPY) $@ $@ -R .comment - rm -f image-coff.o - -vmlinux.coff: coffboot $(HACKCOFF) - $(OBJCOPY) $(OBJCOPY_ARGS) coffboot ../images/$@ - $(HACKCOFF) ../images/$@ - rm -f coffboot - ln -sf vmlinux.coff ../images/zImage.pmac - -vmlinux.initrd.coff: coffboot.initrd $(HACKCOFF) - $(OBJCOPY) $(OBJCOPY_ARGS) coffboot.initrd ../images/$@ - $(HACKCOFF) ../images/$@ - rm -f coffboot.initrd - ln -sf vmlinux.initrd.coff ../images/zImage.initrd.pmac - -vmlinux.elf-pmac: $(CHRPOBJS) $(LIBS) $(MKNOTE) image.o - $(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) $(LIBS) image.o - $(MKNOTE) > note - $(OBJCOPY) ../images/$@ ../images/$@ --add-section=.note=note \ - -R .comment -R .ramdisk - rm -f note - -vmlinux.initrd.elf-pmac: $(CHRPOBJS) $(LIBS) $(MKNOTE) image.o \ - ../images/ramdisk.image.gz - $(OBJCOPY) image.o image-elf.o \ - --add-section=.ramdisk=../images/ramdisk.image.gz \ - --set-section-flags=.ramdisk=contents,alloc,load,readonly,data - $(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) $(LIBS) image-elf.o - $(MKNOTE) > note - $(OBJCOPY) ../images/$@ ../images/$@ --add-section=.note=note \ - -R .comment - rm -f note image-elf.o - -zImage: vmlinux.coff vmlinux.elf-pmac miboot.image - -zImage.initrd: vmlinux.initrd.coff vmlinux.initrd.elf-pmac miboot.initrd.image - -include $(TOPDIR)/Rules.make diff --git a/arch/ppc/boot/pmac/start.c b/arch/ppc/boot/pmac/start.c deleted file mode 100644 index 5a3cbd3b393f..000000000000 --- a/arch/ppc/boot/pmac/start.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (C) Paul Mackerras 1997. - * - * 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 <stdarg.h> - -extern int strlen(const char *s); -extern void boot(int a1, int a2, void *prom); - -int (*prom)(void *); - -void *chosen_handle; -void *stdin; -void *stdout; -void *stderr; - -void exit(void); -void *finddevice(const char *name); -int getprop(void *phandle, const char *name, void *buf, int buflen); -void printk(char *fmt, ...); - -void -start(int a1, int a2, void *promptr) -{ - prom = (int (*)(void *)) promptr; - chosen_handle = finddevice("/chosen"); - if (chosen_handle == (void *) -1) - exit(); - if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4) - exit(); - stderr = stdout; - if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) - exit(); - - boot(a1, a2, promptr); - for (;;) - exit(); -} - -int -write(void *handle, void *ptr, int nb) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *ihandle; - void *addr; - int len; - int actual; - } args; - - args.service = "write"; - args.nargs = 3; - args.nret = 1; - args.ihandle = handle; - args.addr = ptr; - args.len = nb; - args.actual = -1; - (*prom)(&args); - return args.actual; -} - -int writestring(void *f, char *ptr, int nb) -{ - int w = 0, i; - char *ret = "\r"; - - for (i = 0; i < nb; ++i) { - if (ptr[i] == '\n') { - if (i > w) { - write(f, ptr + w, i - w); - w = i; - } - write(f, ret, 1); - } - } - if (w < nb) - write(f, ptr + w, nb - w); - return nb; -} - -int -read(void *handle, void *ptr, int nb) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *ihandle; - void *addr; - int len; - int actual; - } args; - - args.service = "read"; - args.nargs = 3; - args.nret = 1; - args.ihandle = handle; - args.addr = ptr; - args.len = nb; - args.actual = -1; - (*prom)(&args); - return args.actual; -} - -void -exit(void) -{ - struct prom_args { - char *service; - } args; - - for (;;) { - args.service = "exit"; - (*prom)(&args); - } -} - -void -pause(void) -{ - struct prom_args { - char *service; - } args; - - args.service = "enter"; - (*prom)(&args); -} - -void * -finddevice(const char *name) -{ - struct prom_args { - char *service; - int nargs; - int nret; - const char *devspec; - void *phandle; - } args; - - args.service = "finddevice"; - args.nargs = 1; - args.nret = 1; - args.devspec = name; - args.phandle = (void *) -1; - (*prom)(&args); - return args.phandle; -} - -void * -claim(unsigned int virt, unsigned int size, unsigned int align) -{ - struct prom_args { - char *service; - int nargs; - int nret; - unsigned int virt; - unsigned int size; - unsigned int align; - void *ret; - } args; - - args.service = "claim"; - args.nargs = 3; - args.nret = 1; - args.virt = virt; - args.size = size; - args.align = align; - (*prom)(&args); - return args.ret; -} - -void -release(void *virt, unsigned int size) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *virt; - unsigned int size; - } args; - - args.service = "release"; - args.nargs = 2; - args.nret = 0; - args.virt = virt; - args.size = size; - (*prom)(&args); -} - -int -getprop(void *phandle, const char *name, void *buf, int buflen) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *phandle; - const char *name; - void *buf; - int buflen; - int size; - } args; - - args.service = "getprop"; - args.nargs = 4; - args.nret = 1; - args.phandle = phandle; - args.name = name; - args.buf = buf; - args.buflen = buflen; - args.size = -1; - (*prom)(&args); - return args.size; -} - -int -putc(int c, void *f) -{ - char ch = c; - - return writestring(f, &ch, 1) == 1? c: -1; -} - -int -putchar(int c) -{ - return putc(c, stdout); -} - -int -fputs(char *str, void *f) -{ - int n = strlen(str); - - return writestring(f, str, n) == n? 0: -1; -} - -int -readchar(void) -{ - char ch; - - for (;;) { - switch (read(stdin, &ch, 1)) { - case 1: - return ch; - case -1: - printk("read(stdin) returned -1\n"); - return -1; - } - } -} - -static char line[256]; -static char *lineptr; -static int lineleft; - -int -getchar(void) -{ - int c; - - if (lineleft == 0) { - lineptr = line; - for (;;) { - c = readchar(); - if (c == -1 || c == 4) - break; - if (c == '\r' || c == '\n') { - *lineptr++ = '\n'; - putchar('\n'); - break; - } - switch (c) { - case 0177: - case '\b': - if (lineptr > line) { - putchar('\b'); - putchar(' '); - putchar('\b'); - --lineptr; - } - break; - case 'U' & 0x1F: - while (lineptr > line) { - putchar('\b'); - putchar(' '); - putchar('\b'); - --lineptr; - } - break; - default: - if (lineptr >= &line[sizeof(line) - 1]) - putchar('\a'); - else { - putchar(c); - *lineptr++ = c; - } - } - } - lineleft = lineptr - line; - lineptr = line; - } - if (lineleft == 0) - return -1; - --lineleft; - return *lineptr++; -} - -extern int vsprintf(char *buf, const char *fmt, va_list args); -static char sprint_buf[1024]; - -void -printk(char *fmt, ...) -{ - va_list args; - int n; - - va_start(args, fmt); - n = vsprintf(sprint_buf, fmt, args); - va_end(args); - writestring(stdout, sprint_buf, n); -} - -int -printf(char *fmt, ...) -{ - va_list args; - int n; - - va_start(args, fmt); - n = vsprintf(sprint_buf, fmt, args); - va_end(args); - writestring(stdout, sprint_buf, n); - return n; -} diff --git a/arch/ppc/boot/prep/Makefile b/arch/ppc/boot/prep/Makefile index 44e05f6e206b..481644888571 100644 --- a/arch/ppc/boot/prep/Makefile +++ b/arch/ppc/boot/prep/Makefile @@ -19,13 +19,14 @@ TFTPIMAGE = $(TFTPBOOT).smp endif LD_ARGS = -T ../ld.script -Ttext 0x00800000 -Bstatic -boot-y := head.o ../simple/legacy.o misc.o of1275.o \ +boot-y := head.o ../simple/legacy.o misc.o \ ../common/util.o ../common/string.o \ - ../common/misc-common.o + ../common/misc-common.o \ + ../common/mpc10x_memory.o OBJCOPY_ARGS = -O elf32-powerpc LIBS = ../lib/zlib.a -boot-$($CONFIG_SERIAL_8250_CONSOLE) += ../common/ns16550.o +boot-$(CONFIG_SERIAL_8250_CONSOLE) += ../common/ns16550.o boot-$(CONFIG_VGA_CONSOLE) += vreset.o kbd.o EXTRA_TARGETS := $(boot-y) diff --git a/arch/ppc/boot/prep/head.S b/arch/ppc/boot/prep/head.S index dd4057ac4546..9ef410374b37 100644 --- a/arch/ppc/boot/prep/head.S +++ b/arch/ppc/boot/prep/head.S @@ -34,10 +34,6 @@ start_: isync mr r11,r3 /* Save pointer to residual/board data */ - mr r25,r5 /* Save OFW pointer */ - - /* Save the original MSR value */ - mfmsr r26 /* Establish default MSR value */ li r3,MSR_IP|MSR_FP @@ -110,17 +106,11 @@ start_ldr: li r2,0x000F /* Mask pointer to 16-byte boundary */ andc r1,r1,r2 - /* Store the original MSR into 'orig_MSR' */ - lis r3,orig_MSR@h - ori r3,r3,orig_MSR@l - stw r26,0(r3) - /* Run loader */ mr r3,r8 /* Load point */ mr r4,r7 /* Program length */ mr r5,r6 /* Checksum */ mr r6,r11 /* Residual data */ - mr r7,r25 /* OFW interfaces */ bl decompress_kernel /* diff --git a/arch/ppc/boot/prep/misc.c b/arch/ppc/boot/prep/misc.c index cea1093b3f6c..c92348aa6572 100644 --- a/arch/ppc/boot/prep/misc.c +++ b/arch/ppc/boot/prep/misc.c @@ -18,6 +18,7 @@ #include <asm/bootinfo.h> #include <asm/mmu.h> #include <asm/byteorder.h> + #include "nonstdio.h" #include "zlib.h" @@ -49,7 +50,6 @@ int keyb_present = 1; /* keyboard controller is present by default */ RESIDUAL hold_resid_buf; RESIDUAL *hold_residual = &hold_resid_buf; unsigned long initrd_size = 0; -unsigned long orig_MSR; char *zimage_start; int zimage_size; @@ -64,16 +64,11 @@ int orig_x, orig_y = 24; #endif /* CONFIG_VGA_CONSOLE */ extern int CRT_tstc(void); -extern void of_init(void *handler); -extern int of_finddevice(const char *device_specifier, int *phandle); -extern int of_getprop(int phandle, const char *name, void *buf, int buflen, - int *size); extern int vga_init(unsigned char *ISA_mem); extern void gunzip(void *, int, unsigned char *, int *); - -extern void _put_MSR(unsigned int val); extern unsigned long serial_init(int chan, void *ignored); extern void serial_fixups(void); +extern unsigned long get_mem_size(void); void writel(unsigned int val, unsigned int address) @@ -118,15 +113,12 @@ scroll(void) unsigned long decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, - RESIDUAL *residual, void *OFW_interface) + RESIDUAL *residual) { int timer = 0; extern unsigned long start; char *cp, ch; unsigned long TotalMemory; - int dev_handle; - int mem_info[2]; - int res, size; unsigned char board_type; unsigned char base_mod; int start_multi = 0; @@ -140,6 +132,11 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, vga_init((unsigned char *)0xC0000000); #endif /* CONFIG_VGA_CONSOLE */ + /* + * Find out how much memory we have. + */ + TotalMemory = get_mem_size(); + /* * Tell the user where we were loaded at and where we were relocated * to for debugging this process. @@ -216,47 +213,6 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, } else { /* Tell the user we didn't find anything. */ puts("No residual data found.\n"); - - /* Assume 32M in the absence of more info... */ - TotalMemory = 0x02000000; - - /* - * This is a 'best guess' check. We want to make sure - * we don't try this on a PReP box without OF - * -- Cort - */ - while (OFW_interface && ((unsigned long)OFW_interface < 0x10000000) ) - { - /* We need to restore the slightly inaccurate - * MSR so that OpenFirmware will behave. -- Tom - */ - _put_MSR(orig_MSR); - of_init(OFW_interface); - - /* get handle to memory description */ - res = of_finddevice("/memory@0", - &dev_handle); - if (res) - break; - - /* get the info */ - res = of_getprop(dev_handle, - "reg", - mem_info, - sizeof(mem_info), - &size); - if (res) - break; - - TotalMemory = mem_info[1]; - break; - } - - hold_residual->TotalMemory = TotalMemory; - residual = hold_residual; - - /* Enforce a sane MSR for booting. */ - _put_MSR(MSR_IP); } /* assume the chunk below 8M is free */ @@ -361,6 +317,11 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, sizeof(unsigned long); rec = (struct bi_record *)((unsigned long)rec + rec->size); + rec->tag = BI_MEMSIZE; + rec->data[0] = TotalMemory; + rec->size = sizeof(struct bi_record) + sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + rec->tag = BI_CMD_LINE; memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1); rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1; diff --git a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile index 1f13aba690e4..adcd8a76a65c 100644 --- a/arch/ppc/boot/simple/Makefile +++ b/arch/ppc/boot/simple/Makefile @@ -3,11 +3,21 @@ # # Author: Tom Rini <trini@mvista.com> # -# Copyright 2001 MontaVista Software Inc. +# Copyright 2001-2002 MontaVista Software Inc. # -# Notes: For machine targets which produce more than one image, define +# Notes: +# (1) For machine targets which produce more than one image, define # ZNETBOOT and ZNETBOOTRD to the image which should be available for # 'znetboot' and 'znetboot.initrd` +# (2) Also, for machine targets which just need to remove the ELF header, +# define END to be the machine name you want in the image. +# (3) For machine targets which use the mktree program, define END to be +# the machine name you want in the image, and you can optionally set +# ENTRYPOINT which the image should be loaded at. The optimal setting +# for ENTRYPOINT is the link address. +# (4) It is advisable to pass in the memory size using BI_MEMSIZE and +# get_mem_size(), which is memory controller dependant. Add in the correct +# XXX_memory.o file for this to work, as well as editing the $(MISC) file. # # 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 @@ -17,40 +27,36 @@ # Normally, we use the 'misc-simple.c' file for decompress_kernel and # whatnot. Sometimes we need to override this however. MISC := ../common/misc-simple.o -ifeq ($(CONFIG_TREEBOOT),y) +ifeq ($(CONFIG_IBM_OPENBIOS),y) ZIMAGE := zImage-TREE ZIMAGEINITRD := zImage.initrd-TREE -TFTPIMAGE := /tftpboot/zImage.embedded +END := treeboot +TFTPIMAGE := /tftpboot/zImage.$(END) MISC := misc-embedded.o endif ifeq ($(CONFIG_EMBEDDEDBOOT),y) -ZIMAGE := zImage-EMBEDDED -ZIMAGEINITRD := zImage.initrd-EMBEDDED TFTPIMAGE := /tftpboot/zImage.embedded MISC := misc-embedded.o endif ifeq ($(CONFIG_EV64260),y) -ZIMAGE := zImage-EV64260 -ZIMAGEINITRD := zImage.initrd-EV64260 -HEADHELP := direct.o misc-ev64260.o +EXTRA := direct.o misc-ev64260.o TFTPIMAGE := /tftpboot/zImage.ev64260 endif ifeq ($(CONFIG_GEMINI),y) -ZIMAGE := zImage-SMON -ZIMAGEINITRD := zImage.initrd-SMON -HEADHELP := direct.o -TFTPIMAGE := /tftpboot/zImage.gemini +ZIMAGE := zImage-STRIPELF +ZIMAGEINITRD := zImage.initrd-STRIPELF +EXTRA := direct.o +END := gemini +TFTPIMAGE := /tftpboot/zImage.$(END) endif ifeq ($(CONFIG_MENF1),y) ZIMAGE := zImage-MENF1 ZIMAGEINITRD := zImage.initrd-MENF1 -HEADHELP := chrpmap.o +EXTRA := chrpmap.o TFTPIMAGE := /tftpboot/zImage.menf1 endif ifeq ($(CONFIG_K2),y) -ZIMAGE := zImage-K2 -ZIMAGEINITRD := zImage.initrd-K2 -HEADHELP := legacy.o +EXTRA := legacy.o TFTPIMAGE := /tftpboot/zImage.k2 endif # kbuild-2.4 'feature', only one of these will ever by 'y' at a time. @@ -58,45 +64,50 @@ endif ifeq ($(CONFIG_MCPN765)$(CONFIG_MVME5100)$(CONFIG_PRPMC750)$(CONFIG_PRPMC800)$(CONFIG_LOPEC)$(CONFIG_PPLUS),y) ZIMAGE := zImage-PPLUS ZIMAGEINITRD := zImage.initrd-PPLUS -HEADHELP := direct.o +EXTRA := direct.o TFTPIMAGE := /tftpboot/zImage.pplus ZNETBOOT := zImage.pplus ZNETBOOTRD := zImage.initrd.pplus endif ifeq ($(CONFIG_PPLUS),y) -HEADHELP := legacy.o +EXTRA := legacy.o +endif +ifeq ($(CONFIG_LOPEC),y) +EXTRA += ../common/mpc10x_memory.o +endif +ifeq ($(CONFIG_PAL4),y) +EXTRA := direct.o ../common/cpc700_memory.o endif -ifeq ($(CONFIG_PCORE),y) -ZIMAGE := zImage-PCORE -ZIMAGEINITRD := zImage.initrd-PCORE -HEADHELP := chrpmap.o -TFTPIMAGE := /tftpboot/zImage.pcore +ifeq ($(CONFIG_PCORE)$(CONFIG_POWERPMC250),y) +ZIMAGE := zImage-STRIPELF +ZIMAGEINITRD := zImage.initrd-STRIPELF +EXTRA := chrpmap.o +END := pcore +TFTPIMAGE := /tftpboot/zImage.$(END) endif -#Ugh, should come up with a better nameing convention.. +# The PowerPMC 250 needs the dummy serial_fixups() ifeq ($(CONFIG_POWERPMC250),y) -ZIMAGE := zImage-PCORE -ZIMAGEINITRD := zImage.initrd-PCORE -HEADHELP := direct.o -TFTPIMAGE := /tftpboot/zImage.pcore +EXTRA := direct.o endif ifeq ($(CONFIG_SANDPOINT),y) -ZIMAGE := zImage-SP -ZIMAGEINITRD := zImage.initrd-SP -HEADHELP := direct.o +EXTRA := direct.o TFTPIMAGE := /tftpboot/zImage.sandpoint endif ifeq ($(CONFIG_SPRUCE),y) -ZIMAGE := zImage-SPRUCE -ZIMAGEINITRD := zImage.initrd-SPRUCE -HEADHELP := direct.o +ZIMAGE := zImage-TREE +ZIMAGEINITRD := zImage.initrd-TREE +EXTRA := direct.o +END := spruce +ENTRYPOINT := 0x00800000 MISC := misc-spruce.o -TFTPIMAGE := /tftpboot/zImage.spruce +TFTPIMAGE := /tftpboot/zImage.$(END) endif ifeq ($(CONFIG_ZX4500),y) -ZIMAGE := zImage-ZX4500 -ZIMAGEINITRD := zImage.initrd-ZX4500 -HEADHELP := direct.o -TFTPIMAGE := /tftpboot/zImage.zx4500 +ZIMAGE := zImage-STRIPELF +ZIMAGEINITRD := zImage.initrd-STRIPELF +EXTRA := direct.o +END := zx4500 +TFTPIMAGE := /tftpboot/zImage.$(END) endif ifeq ($(CONFIG_SMP),y) TFTPIMAGE += .smp @@ -105,7 +116,7 @@ ifeq ($(CONFIG_REDWOOD_4),y) # This is a treeboot that needs init functions until the # boot rom is sorted out (i.e. this is short lived) EXTRA_AFLAGS := -Wa,-m405 -HEADHELP := rw4/rw4_init.o rw4/rw4_init_brd.o +EXTRA := rw4/rw4_init.o rw4/rw4_init_brd.o endif # Default linker args. Link at 0x00800000 or 0x00400000 by default, but @@ -122,7 +133,7 @@ endif OBJCOPY_ARGS := -O elf32-powerpc # head.o and ../common/relocate.o must be at the start. -boot-y := head.o ../common/relocate.o $(HEADHELP) \ +boot-y := head.o ../common/relocate.o $(EXTRA) \ $(MISC) ../common/misc-common.o \ ../common/string.o ../common/util.o boot-$(CONFIG_4xx) += embed_config.o @@ -170,9 +181,12 @@ zvmlinux.initrd: $(boot-y) $(LIBS) ../ld.script ../images/vmlinux.gz \ -R .sysmap # Sort-of dummy rules, that let us format the image we want. -zImage: $(ZIMAGE) +zImage: $(ZIMAGE) zvmlinux + cp -f zvmlinux ../images/zImage.elf rm -f zvmlinux -zImage.initrd: $(ZIMAGEINITRD) + +zImage.initrd: $(ZIMAGEINITRD) zvmlinux.initrd + cp -f zvmlinux.initrd ../images/zImage.initrd.elf rm -f zvmlinux.initrd znetboot: zImage @@ -189,23 +203,17 @@ else cp ../images/zImage.* $(TFTPIMAGE) endif -zImage-EMBEDDED: zvmlinux - mv zvmlinux ../images/zImage.embedded +zImage-STRIPELF: zvmlinux + dd if=zvmlinux of=../images/zImage.$(END) skip=64 bs=1k -zImage.initrd-EMBEDDED: zvmlinux.initrd - mv zvmlinux.initrd ../images/zImage.initrd.embedded +zImage.initrd-STRIPELF: zvmlinux.initrd + dd if=zvmlinux.initrd of=../images/zImage.initrd.$(END) skip=64 bs=1k -zImage-K2: zvmlinux - mv zvmlinux ../images/zImage.k2 - -zImage.initrd-K2: zvmlinux.initrd - mv zvmlinux.initrd ../images/zImage.initrd.k2 - -zImage-EV64260: zvmlinux - mv zvmlinux ../images/zImage.ev64260 +zImage-TREE: zvmlinux + $(MKTREE) zvmlinux ../images/zImage.$(END) $(ENTRYPOINT) -zImage.initrd-EV64260: zvmlinux.initrd - mv zvmlinux.initrd ../images/zImage.initrd.ev64260 +zImage.initrd-TREE: zvmlinux.initrd + $(MKTREE) zvmlinux.initrd ../images/zImage.initrd.$(END) $(ENTRYPOINT) zImage-MENF1: zvmlinux $(MKPREP) -pbp zvmlinux ../images/zImage.menf1 @@ -213,12 +221,6 @@ zImage-MENF1: zvmlinux zImage.initrd-MENF1: zvmlinux.initrd $(MKPREP) -pbp zvmlinux.initrd ../images/zImage.initrd.menf1 -zImage-PCORE: zvmlinux - dd if=zvmlinux of=../images/zImage.pcore skip=64 bs=1k - -zImage.initrd-PCORE: zvmlinux.initrd - dd if=zvmlinux.initrd of=../images/zImage.initrd.pcore skip=64 bs=1k - zImage-PPLUS: zvmlinux $(MKPREP) $(MKBUGBOOT) $(MKPREP) -pbp zvmlinux ../images/zImage.pplus $(MKBUGBOOT) zvmlinux ../images/zImage.bugboot @@ -227,34 +229,4 @@ zImage.initrd-PPLUS: zvmlinux.initrd $(MKPREP) $(MKBUGBOOT) $(MKPREP) -pbp zvmlinux.initrd ../images/zImage.initrd.pplus $(MKBUGBOOT) zvmlinux.initrd ../images/zImage.initrd.bugboot -zImage-SMON: zvmlinux - dd if=zvmlinux of=../images/zImage.gemini skip=64 bs=1k - -zImage.initrd-SMON: zvmlinux.initrd - dd if=zvmlinux.initrd of=../images/zImage.initrd.gemini skip=64 bs=1k - -zImage-SP: zvmlinux - mv zvmlinux ../images/zImage.sandpoint - -zImage.initrd-SP: zvmlinux.initrd - mv zvmlinux.initrd ../images/zImage.initrd.sandpoint - -zImage-SPRUCE: zvmlinux - $(MKTREE) zvmlinux ../images/zImage.spruce 0x800000 - -zImage.initrd-SPRUCE: zvmlinux.initrd - $(MKTREE) zvmlinux.initrd ../images/zImage.initrd.spruce 0x800000 - -zImage-TREE: zvmlinux - $(MKTREE) zvmlinux ../images/zImage.treeboot - -zImage.initrd-TREE: zvmlinux.initrd - $(MKTREE) zvmlinux.initrd ../images/zImage.initrd.treeboot - -zImage-ZX4500: zvmlinux - dd if=zvmlinux of=../images/zImage.zx4500 skip=64 bs=1k - -zImage.initrd-ZX4500: zvmlinux.initrd - dd if=zvmlinux.initrd of=../images/zImage.initrd.zx4500 skip=64 bs=1k - include $(TOPDIR)/Rules.make diff --git a/arch/ppc/boot/simple/embed_config.c b/arch/ppc/boot/simple/embed_config.c index 9ad389da640e..c298d7a7c6f5 100644 --- a/arch/ppc/boot/simple/embed_config.c +++ b/arch/ppc/boot/simple/embed_config.c @@ -10,7 +10,6 @@ #include <linux/types.h> #include <linux/config.h> #include <linux/string.h> -#include <asm/io.h> #ifdef CONFIG_8xx #include <asm/mpc8xx.h> #endif @@ -18,6 +17,9 @@ #include <asm/mpc8260.h> #include <asm/immap_8260.h> #endif +#ifdef CONFIG_40x +#include <asm/io.h> +#endif /* For those boards that don't provide one. */ @@ -653,15 +655,65 @@ embed_config(bd_t **bdp) } #endif /* WILLOW */ -#ifdef CONFIG_TREEBOOT +void +embed_config(bd_t ** bdp) +{ + static const unsigned long line_size = 32; + static const unsigned long congruence_classes = 256; + unsigned long addr; + u_char *cp; + int i; + bd_t *bd; + + /* + * At one point, we were getting machine checks. Linux was not + * invalidating the data cache before it was enabled. The + * following code was added to do that. Soon after we had done + * that, we found the real reasons for the machine checks. I've + * run the kernel a few times with the following code + * temporarily removed without any apparent problems. However, + * I objdump'ed the kernel and boot code and found out that + * there were no other dccci's anywhere, so I put the code back + * in and have been reluctant to remove it. It seems safer to + * just leave it here. + */ + for (addr = 0; + addr < (congruence_classes * line_size); addr += line_size) { + __asm__("dccci 0,%0": :"b"(addr)); + } + + bd = &bdinfo; + *bdp = bd; + bd->bi_memsize = XPAR_DDR_0_SIZE; + bd->bi_intfreq = XPAR_CORE_CLOCK_FREQ_HZ; + bd->bi_busfreq = XPAR_PLB_CLOCK_FREQ_HZ; +} + +#ifdef CONFIG_IBM_OPENBIOS /* This could possibly work for all treeboot roms. */ -#if defined(CONFIG_ASH) +#if defined(CONFIG_ASH) || defined(CONFIG_BEECH) #define BOARD_INFO_VECTOR 0xFFF80B50 /* openbios 1.19 moved this vector down - armin */ #else -#define BOARD_INFO_VECTOR 0xFFFE0B50 +#define BOARD_INFO_VECTOR 0xFFFE0B50 #endif +#ifdef CONFIG_BEECH +static void +get_board_info(bd_t **bdp) +{ + typedef void (*PFV)(bd_t *bd); + ((PFV)(*(unsigned long *)BOARD_INFO_VECTOR))(*bdp); + return; +} + +void +embed_config(bd_t **bdp) +{ + *bdp = &bdinfo; + get_board_info(bdp); +} +#else /* !CONFIG_BEECH */ void embed_config(bd_t **bdp) { @@ -671,16 +723,13 @@ embed_config(bd_t **bdp) bd_t *(*get_board_info)(void) = (bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR); #if !defined(CONFIG_STB03xxx) - volatile emac_t *emacp; - emacp = (emac_t *)EMAC0_BASE; /* assume 1st emac - armin */ /* shut down the Ethernet controller that the boot rom * sometimes leaves running. */ mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR); /* 1st reset MAL */ while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; /* wait for the reset */ - emacp->em0mr0 = 0x20000000; /* then reset EMAC */ - eieio(); + out_be32(EMAC0_BASE,0x20000000); /* then reset EMAC */ #endif bd = &bdinfo; @@ -711,14 +760,15 @@ embed_config(bd_t **bdp) #endif } /* Yeah, this look weird, but on Redwood 4 they are - * different object in the structure. When RW5 uses - * OpenBIOS, it requires a special value. + * different object in the structure. Sincr Redwwood 5 + * and Redwood 6 use OpenBIOS, it requires a special value. */ -#ifdef CONFIG_REDWOOD_5 +#if defined(CONFIG_REDWOOD_5) || defined (CONFIG_REDWOOD_6) bd->bi_tbfreq = 27 * 1000 * 1000; #endif } -#endif +#endif /* CONFIG_BEECH */ +#endif /* CONFIG_IBM_OPENBIOS */ #ifdef CONFIG_EP405 #include <linux/serial_reg.h> @@ -745,6 +795,14 @@ embed_config(bd_t **bdp) writeb(0, UART0_IO_BASE + UART_LCR); } + /* We haven't seen actual problems with the EP405 leaving the + * EMAC running (as we have on Walnut). But the registers + * suggest it may not be left completely quiescent. Reset it + * just to be sure. */ + mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR); /* 1st reset MAL */ + while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; /* wait for the reset */ + out_be32(EMAC0_BASE,0x20000000); /* then reset EMAC */ + bd = &bdinfo; *bdp = bd; #if 1 @@ -804,6 +862,16 @@ embed_config(bd_t **bdp) bd = &bdinfo; *bdp = bd; + + for(i=0;i<8192;i+=32) { + __asm__("dccci 0,%0" :: "r" (i)); + } + __asm__("iccci 0,0"); + __asm__("sync;isync"); + + /* init ram for parity */ + memset(0, 0,0x400000); /* Lo memory */ + bd->bi_memsize = (32 * 1024 * 1024) ; bd->bi_intfreq = 133000000; //the internal clock is 133 MHz diff --git a/arch/ppc/boot/simple/head.S b/arch/ppc/boot/simple/head.S index 7d661d62c9a7..e3af8ae4da17 100644 --- a/arch/ppc/boot/simple/head.S +++ b/arch/ppc/boot/simple/head.S @@ -37,7 +37,7 @@ .globl start start: bl start_ -#ifdef CONFIG_TREEBOOT +#ifdef CONFIG_IBM_OPENBIOS /* The IBM "Tree" bootrom knows that the address of the bootrom * read only structure is 4 bytes after _start. */ @@ -73,7 +73,8 @@ start_: #ifdef CONFIG_6xx bl disable_6xx_mmu bl disable_6xx_l1cache -#if defined(CONFIG_FORCE) || defined(CONFIG_K2) || defined(CONFIG_EV64260) +#if defined(CONFIG_FORCE) || defined(CONFIG_K2) \ + || defined(CONFIG_EV64260) || defined(CONFIG_PAL4) bl _setup_L2CR #endif #endif diff --git a/arch/ppc/boot/simple/misc-embedded.c b/arch/ppc/boot/simple/misc-embedded.c index 67fb65a40e1c..47b93582f306 100644 --- a/arch/ppc/boot/simple/misc-embedded.c +++ b/arch/ppc/boot/simple/misc-embedded.c @@ -80,7 +80,7 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, b * initialize the serial console port. */ embed_config(&bp); -#ifdef CONFIG_SERIAL_CONSOLE +#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) com_port = serial_init(0, bp); #endif |
