diff options
| author | Tom Rini <trini@kernel.crashing.org> | 2002-09-18 11:18:20 +1000 |
|---|---|---|
| committer | Paul Mackerras <paulus@samba.org> | 2002-09-18 11:18:20 +1000 |
| commit | 037bd2fdff2707eca2fb54515cb36b1517af0e9b (patch) | |
| tree | fc34f99d1a0e227784d8621d7fa06b90bd35d26b /arch/ppc/boot | |
| parent | 8c6c406e33719e56b1f2592b01554924b593b1f1 (diff) | |
PPC32: Boot wrapper updates.
The major changes here are:
(1) Combine the pmac and chrp directories into a single
`openfirmware' directory, since both use Open Firmware and the code
was very similar.
(2) Move the Open Firmware interfaces out to a `of1275' directory
and put them in separate files so we only include the ones we need.
This work is due to Leigh Brown.
(3) On PReP and embedded, get the memory size from the memory
controller. Don't try to ask Open Firmware even on PRePs which
have it.
Diffstat (limited to 'arch/ppc/boot')
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 |
