aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/Makefile7
-rw-r--r--arch/powerpc/boot/Makefile49
-rw-r--r--arch/powerpc/boot/crt0.S21
-rw-r--r--arch/powerpc/boot/hack-coff.c84
-rw-r--r--arch/powerpc/boot/main.c46
-rw-r--r--arch/powerpc/boot/prom.c538
-rw-r--r--arch/powerpc/boot/prom.h36
-rw-r--r--arch/powerpc/boot/rs6000.h243
-rw-r--r--arch/powerpc/boot/stdio.c325
-rw-r--r--arch/powerpc/boot/stdio.h6
-rw-r--r--arch/powerpc/boot/string.S20
-rw-r--r--arch/powerpc/boot/zImage.coff.lds46
-rw-r--r--arch/powerpc/configs/mpc834x_sys_defconfig911
-rw-r--r--arch/powerpc/kernel/asm-offsets.c2
-rw-r--r--arch/powerpc/kernel/cpu_setup_power4.S4
-rw-r--r--arch/powerpc/kernel/cputable.c224
-rw-r--r--arch/powerpc/kernel/entry_32.S2
-rw-r--r--arch/powerpc/kernel/entry_64.S15
-rw-r--r--arch/powerpc/kernel/fpu.S10
-rw-r--r--arch/powerpc/kernel/head_64.S112
-rw-r--r--arch/powerpc/kernel/idle_power4.S8
-rw-r--r--arch/powerpc/kernel/irq.c12
-rw-r--r--arch/powerpc/kernel/lparcfg.c13
-rw-r--r--arch/powerpc/kernel/misc_32.S4
-rw-r--r--arch/powerpc/kernel/misc_64.S10
-rw-r--r--arch/powerpc/kernel/paca.c36
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c3
-rw-r--r--arch/powerpc/kernel/prom.c109
-rw-r--r--arch/powerpc/kernel/prom_parse.c3
-rw-r--r--arch/powerpc/kernel/rtas.c96
-rw-r--r--arch/powerpc/kernel/setup-common.c9
-rw-r--r--arch/powerpc/kernel/time.c2
-rw-r--r--arch/powerpc/lib/locks.c8
-rw-r--r--arch/powerpc/oprofile/common.c8
-rw-r--r--arch/powerpc/platforms/83xx/Kconfig1
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_sys.c243
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_sys.h23
-rw-r--r--arch/powerpc/platforms/83xx/mpc83xx.h14
-rw-r--r--arch/powerpc/platforms/83xx/pci.c99
-rw-r--r--arch/powerpc/platforms/chrp/pci.c27
-rw-r--r--arch/powerpc/platforms/chrp/setup.c7
-rw-r--r--arch/powerpc/platforms/chrp/time.c7
-rw-r--r--arch/powerpc/platforms/iseries/irq.c6
-rw-r--r--arch/powerpc/platforms/iseries/misc.S3
-rw-r--r--arch/powerpc/platforms/iseries/setup.c8
-rw-r--r--arch/powerpc/platforms/iseries/smp.c2
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c4
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c100
-rw-r--r--arch/powerpc/platforms/pseries/setup.c20
-rw-r--r--arch/powerpc/sysdev/Makefile1
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c317
-rw-r--r--arch/powerpc/sysdev/fsl_soc.h8
52 files changed, 3163 insertions, 749 deletions
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index d3654a264ef..44dd82b791d 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -139,17 +139,14 @@ drivers-$(CONFIG_CPM2) += arch/ppc/8260_io/
drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
-defaultimage-$(CONFIG_PPC32) := zImage
+# Default to zImage, override when needed
+defaultimage-y := zImage
defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux
-defaultimage-$(CONFIG_PPC_PSERIES) := zImage
KBUILD_IMAGE := $(defaultimage-y)
all: $(KBUILD_IMAGE)
CPPFLAGS_vmlinux.lds := -Upowerpc
-# All the instructions talk about "make bzImage".
-bzImage: zImage
-
BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm uImage
.PHONY: $(BOOT_TARGETS)
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index b53d677f674..788dec4c7ef 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -25,8 +25,8 @@ HOSTCC := gcc
BOOTCFLAGS := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem \
$(shell $(CROSS32CC) -print-file-name=include) -fPIC
BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc
-BOOTLFLAGS := -T $(srctree)/$(src)/zImage.lds
OBJCOPYFLAGS := contents,alloc,load,readonly,data
+OBJCOPY_COFF_ARGS := -O aixcoff-rs6000 --set-start 0x500000
zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c
zlibheader := infblock.h infcodes.h inffast.h inftrees.h infutil.h
@@ -35,7 +35,7 @@ zliblinuxheader := zlib.h zconf.h zutil.h
$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
#$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h)
-src-boot := string.S prom.c main.c div64.S crt0.S
+src-boot := crt0.S string.S prom.c stdio.c main.c div64.S
src-boot += $(zlib)
src-boot := $(addprefix $(obj)/, $(src-boot))
obj-boot := $(addsuffix .o, $(basename $(src-boot)))
@@ -70,7 +70,7 @@ quiet_cmd_bootas = BOOTAS $@
cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $<
quiet_cmd_bootld = BOOTLD $@
- cmd_bootld = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(2)
+ cmd_bootld = $(CROSS32LD) -T $(srctree)/$(src)/$(3) -o $@ $(2)
$(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c
$(call if_changed_dep,bootcc)
@@ -87,12 +87,14 @@ obj-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.o, $(section)))
src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section)))
gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section)))
-hostprogs-y := addnote addRamDisk
-targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd \
- $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \
- $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \
- $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \
- vmlinux.initrd
+hostprogs-y := addnote addRamDisk hack-coff
+
+targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd \
+ zImage.coff zImage.initrd.coff \
+ $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \
+ $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \
+ $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \
+ vmlinux.initrd
extra-y := initrd.o
quiet_cmd_ramdisk = RAMDISK $@
@@ -114,6 +116,10 @@ quiet_cmd_addsection = ADDSEC $@
quiet_cmd_addnote = ADDNOTE $@
cmd_addnote = $(obj)/addnote $@
+quiet_cmd_gencoff = COFF $@
+ cmd_gencoff = $(OBJCOPY) $(OBJCOPY_COFF_ARGS) $@ && \
+ $(obj)/hack-coff $@
+
$(call gz-sec, $(required)): $(obj)/kernel-%.gz: %
$(call if_changed,gzip)
@@ -127,22 +133,35 @@ $(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c
$(call if_changed_dep,bootcc)
$(call cmd,addsection)
-$(obj)/zImage.vmode: obj-boot += $(call obj-sec, $(required))
+$(obj)/zImage.vmode $(obj)/zImage.coff: obj-boot += $(call obj-sec, $(required))
$(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) $(srctree)/$(src)/zImage.lds
- $(call cmd,bootld,$(obj-boot))
+ $(call cmd,bootld,$(obj-boot),zImage.lds)
-$(obj)/zImage.initrd.vmode: obj-boot += $(call obj-sec, $(required) $(initrd))
+$(obj)/zImage.initrd.vmode $(obj)/zImage.initrd.coff: obj-boot += $(call obj-sec, $(required) $(initrd))
$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(srctree)/$(src)/zImage.lds
- $(call cmd,bootld,$(obj-boot))
+ $(call cmd,bootld,$(obj-boot),zImage.lds)
+
+# For 32-bit powermacs, build the COFF images as well as the ELF images.
+coffimage-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/zImage.coff
+coffrdimg-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/zImage.initrd.coff
-$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote
+$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote $(coffimage-y-y)
@cp -f $< $@
$(call if_changed,addnote)
-$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote
+$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote $(coffrdimg-y-y)
@cp -f $< $@
$(call if_changed,addnote)
+$(obj)/zImage.coff: $(call obj-sec, $(required)) $(obj-boot) $(srctree)/$(src)/zImage.coff.lds $(obj)/hack-coff
+ $(call cmd,bootld,$(obj-boot),zImage.coff.lds)
+ $(call cmd,gencoff)
+
+$(obj)/zImage.initrd.coff: $(call obj-sec, $(required) $(initrd)) $(obj-boot) \
+ $(srctree)/$(src)/zImage.coff.lds $(obj)/hack-coff
+ $(call cmd,bootld,$(obj-boot),zImage.coff.lds)
+ $(call cmd,gencoff)
+
#-----------------------------------------------------------
# build u-boot images
#-----------------------------------------------------------
diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S
index d2f2ace56cd..e0192c26037 100644
--- a/arch/powerpc/boot/crt0.S
+++ b/arch/powerpc/boot/crt0.S
@@ -12,17 +12,23 @@
#include "ppc_asm.h"
.text
+ /* a procedure descriptor used when booting this as a COFF file */
+_zimage_start_opd:
+ .long _zimage_start, 0, 0, 0
+
.globl _zimage_start
_zimage_start:
+ /* Work out the offset between the address we were linked at
+ and the address where we're running. */
bl 1f
-
-1:
- mflr r0
+1: mflr r0
lis r9,1b@ha
addi r9,r9,1b@l
subf. r0,r9,r0
- beq 3f
+ beq 3f /* if running at same address as linked */
+ /* The .got2 section contains a list of addresses, so add
+ the address offset onto each entry. */
lis r9,__got2_start@ha
addi r9,r9,__got2_start@l
lis r8,__got2_end@ha
@@ -32,15 +38,14 @@ _zimage_start:
srwi. r8,r8,2
mtctr r8
add r9,r0,r9
-2:
- lwz r8,0(r9)
+2: lwz r8,0(r9)
add r8,r8,r0
stw r8,0(r9)
addi r9,r9,4
bdnz 2b
-3:
- lis r9,_start@h
+ /* Do a cache flush for our text, in case OF didn't */
+3: lis r9,_start@h
add r9,r0,r9
lis r8,_etext@ha
addi r8,r8,_etext@l
diff --git a/arch/powerpc/boot/hack-coff.c b/arch/powerpc/boot/hack-coff.c
new file mode 100644
index 00000000000..5e5a6573a1e
--- /dev/null
+++ b/arch/powerpc/boot/hack-coff.c
@@ -0,0 +1,84 @@
+/*
+ * hack-coff.c - hack the header of an xcoff file to fill in
+ * a few fields needed by the Open Firmware xcoff loader on
+ * Power Macs but not initialized by objcopy.
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include "rs6000.h"
+
+#define AOUT_MAGIC 0x010b
+
+#define get_16be(x) ((((unsigned char *)(x))[0] << 8) \
+ + ((unsigned char *)(x))[1])
+#define put_16be(x, v) (((unsigned char *)(x))[0] = (v) >> 8, \
+ ((unsigned char *)(x))[1] = (v) & 0xff)
+#define get_32be(x) ((((unsigned char *)(x))[0] << 24) \
+ + (((unsigned char *)(x))[1] << 16) \
+ + (((unsigned char *)(x))[2] << 8) \
+ + ((unsigned char *)(x))[3])
+
+int
+main(int ac, char **av)
+{
+ int fd;
+ int i, nsect;
+ int aoutsz;
+ struct external_filehdr fhdr;
+ AOUTHDR aout;
+ struct external_scnhdr shdr;
+
+ if (ac != 2) {
+ fprintf(stderr, "Usage: hack-coff coff-file\n");
+ exit(1);
+ }
+ if ((fd = open(av[1], 2)) == -1) {
+ perror(av[2]);
+ exit(1);
+ }
+ if (read(fd, &fhdr, sizeof(fhdr)) != sizeof(fhdr))
+ goto readerr;
+ i = get_16be(fhdr.f_magic);
+ if (i != U802TOCMAGIC && i != U802WRMAGIC && i != U802ROMAGIC) {
+ fprintf(stderr, "%s: not an xcoff file\n", av[1]);
+ exit(1);
+ }
+ aoutsz = get_16be(fhdr.f_opthdr);
+ if (read(fd, &aout, aoutsz) != aoutsz)
+ goto readerr;
+ nsect = get_16be(fhdr.f_nscns);
+ for (i = 0; i < nsect; ++i) {
+ if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr))
+ goto readerr;
+ if (strcmp(shdr.s_name, ".text") == 0) {
+ put_16be(aout.o_snentry, i+1);
+ put_16be(aout.o_sntext, i+1);
+ } else if (strcmp(shdr.s_name, ".data") == 0) {
+ put_16be(aout.o_sndata, i+1);
+ } else if (strcmp(shdr.s_name, ".bss") == 0) {
+ put_16be(aout.o_snbss, i+1);
+ }
+ }
+ put_16be(aout.magic, AOUT_MAGIC);
+ if (lseek(fd, (long) sizeof(struct external_filehdr), 0) == -1
+ || write(fd, &aout, aoutsz) != aoutsz) {
+ fprintf(stderr, "%s: write error\n", av[1]);
+ exit(1);
+ }
+ close(fd);
+ exit(0);
+
+readerr:
+ fprintf(stderr, "%s: read error or file too short\n", av[1]);
+ exit(1);
+}
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c
index 64ec93116fa..55ec5986725 100644
--- a/arch/powerpc/boot/main.c
+++ b/arch/powerpc/boot/main.c
@@ -21,8 +21,8 @@ extern void flush_cache(void *, unsigned long);
/* Value picked to match that used by yaboot */
-#define PROG_START 0x01400000
-#define RAM_END (512<<20) // Fixme: use OF */
+#define PROG_START 0x01400000 /* only used on 64-bit systems */
+#define RAM_END (512<<20) /* Fixme: use OF */
#define ONE_MB 0x100000
extern char _start[];
@@ -160,6 +160,17 @@ static int is_elf64(void *hdr)
elfoffset = (unsigned long)elf64ph->p_offset;
vmlinux.size = (unsigned long)elf64ph->p_filesz + elfoffset;
vmlinux.memsize = (unsigned long)elf64ph->p_memsz + elfoffset;
+
+#if defined(PROG_START)
+ /*
+ * Maintain a "magic" minimum address. This keeps some older
+ * firmware platforms running.
+ */
+
+ if (claim_base < PROG_START)
+ claim_base = PROG_START;
+#endif
+
return 1;
}
@@ -206,12 +217,18 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
exit();
if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
exit();
- stderr = stdout;
- if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
- exit();
printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp);
+ /*
+ * The first available claim_base must be above the end of the
+ * the loaded kernel wrapper file (_start to _end includes the
+ * initrd image if it is present) and rounded up to a nice
+ * 1 MB boundary for good measure.
+ */
+
+ claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
+
vmlinuz.addr = (unsigned long)_vmlinux_start;
vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
@@ -228,25 +245,6 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
exit();
}
- /*
- * The first available claim_base must be above the end of the
- * the loaded kernel wrapper file (_start to _end includes the
- * initrd image if it is present) and rounded up to a nice
- * 1 MB boundary for good measure.
- */
-
- claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
-
-#if defined(PROG_START)
- /*
- * Maintain a "magic" minimum address. This keeps some older
- * firmware platforms running.
- */
-
- if (claim_base < PROG_START)
- claim_base = PROG_START;
-#endif
-
/* We need to claim the memsize plus the file offset since gzip
* will expand the header (file offset), then the kernel, then
* possible rubbish we don't care about. But the kernel bss must
diff --git a/arch/powerpc/boot/prom.c b/arch/powerpc/boot/prom.c
index 4bea2f4dcb0..fa0057736f6 100644
--- a/arch/powerpc/boot/prom.c
+++ b/arch/powerpc/boot/prom.c
@@ -13,487 +13,153 @@
#include "prom.h"
int (*prom)(void *);
+phandle chosen_handle;
+ihandle stdout;
-void *chosen_handle;
-
-void *stdin;
-void *stdout;
-void *stderr;
-
-
-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)
+int call_prom(const char *service, int nargs, int nret, ...)
{
+ int i;
struct prom_args {
- char *service;
+ const 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()
-{
- struct prom_args {
- char *service;
- } args;
-
- for (;;) {
- args.service = "exit";
- (*prom)(&args);
- }
-}
-
-void
-pause(void)
-{
- struct prom_args {
- char *service;
+ unsigned int args[12];
} args;
+ va_list list;
- args.service = "enter";
- (*prom)(&args);
-}
+ args.service = service;
+ args.nargs = nargs;
+ args.nret = nret;
-void *
-finddevice(const char *name)
-{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- const char *devspec;
- void *phandle;
- } args;
+ va_start(list, nret);
+ for (i = 0; i < nargs; i++)
+ args.args[i] = va_arg(list, unsigned int);
+ va_end(list);
- args.service = "finddevice";
- args.nargs = 1;
- args.nret = 1;
- args.devspec = name;
- args.phandle = (void *) -1;
- (*prom)(&args);
- return args.phandle;
-}
+ for (i = 0; i < nret; i++)
+ args.args[nargs+i] = 0;
-void *
-claim(unsigned long virt, unsigned long size, unsigned long align)
-{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- unsigned int virt;
- unsigned int size;
- unsigned int align;
- void *ret;
- } args;
+ if (prom(&args) < 0)
+ return -1;
- args.service = "claim";
- args.nargs = 3;
- args.nret = 1;
- args.virt = virt;
- args.size = size;
- args.align = align;
- (*prom)(&args);
- return args.ret;
+ return (nret > 0)? args.args[nargs]: 0;
}
-int
-getprop(void *phandle, const char *name, void *buf, int buflen)
+int call_prom_ret(const char *service, int nargs, int nret,
+ unsigned int *rets, ...)
{
+ int i;
struct prom_args {
- char *service;
+ const char *service;
int nargs;
int nret;
- void *phandle;
- const char *name;
- void *buf;
- int buflen;
- int size;
+ unsigned int args[12];
} args;
+ va_list list;
- 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;
-}
+ args.service = service;
+ args.nargs = nargs;
+ args.nret = nret;
-int
-putc(int c, void *f)
-{
- char ch = c;
+ va_start(list, rets);
+ for (i = 0; i < nargs; i++)
+ args.args[i] = va_arg(list, unsigned int);
+ va_end(list);
- if (c == '\n')
- putc('\r', f);
- return write(f, &ch, 1) == 1? c: -1;
-}
+ for (i = 0; i < nret; i++)
+ args.args[nargs+i] = 0;
-int
-putchar(int c)
-{
- return putc(c, stdout);
-}
+ if (prom(&args) < 0)
+ return -1;
-int
-fputs(char *str, void *f)
-{
- int n = strlen(str);
+ if (rets != (void *) 0)
+ for (i = 1; i < nret; ++i)
+ rets[i-1] = args.args[nargs+i];
- return write(f, str, n) == n? 0: -1;
+ return (nret > 0)? args.args[nargs]: 0;
}
-size_t strnlen(const char * s, size_t count)
+int write(void *handle, void *ptr, int nb)
{
- const char *sc;
-
- for (sc = s; count-- && *sc != '\0'; ++sc)
- /* nothing */;
- return sc - s;
+ return call_prom("write", 3, 1, handle, ptr, nb);
}
-extern unsigned int __div64_32(unsigned long long *dividend,
- unsigned int divisor);
-
-/* The unnecessary pointer compare is there
- * to check for type safety (n must be 64bit)
+/*
+ * Older OF's require that when claiming a specific range of addresses,
+ * we claim the physical space in the /memory node and the virtual
+ * space in the chosen mmu node, and then do a map operation to
+ * map virtual to physical.
*/
-# define do_div(n,base) ({ \
- unsigned int __base = (base); \
- unsigned int __rem; \
- (void)(((typeof((n)) *)0) == ((unsigned long long *)0)); \
- if (((n) >> 32) == 0) { \
- __rem = (unsigned int)(n) % __base; \
- (n) = (unsigned int)(n) / __base; \
- } else \
- __rem = __div64_32(&(n), __base); \
- __rem; \
- })
+static int need_map = -1;
+static ihandle chosen_mmu;
+static phandle memory;
-static int skip_atoi(const char **s)
+/* returns true if s2 is a prefix of s1 */
+static int string_match(const char *s1, const char *s2)
{
- int i, c;
-
- for (i = 0; '0' <= (c = **s) && c <= '9'; ++*s)
- i = i*10 + c - '0';
- return i;
+ for (; *s2; ++s2)
+ if (*s1++ != *s2)
+ return 0;
+ return 1;
}
-#define ZEROPAD 1 /* pad with zero */
-#define SIGN 2 /* unsigned/signed long */
-#define PLUS 4 /* show plus */
-#define SPACE 8 /* space if plus */
-#define LEFT 16 /* left justified */
-#define SPECIAL 32 /* 0x */
-#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
-
-static char * number(char * str, unsigned long long num, int base, int size, int precision, int type)
+static int check_of_version(void)
{
- char c,sign,tmp[66];
- const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
- int i;
+ phandle oprom, chosen;
+ char version[64];
- if (type & LARGE)
- digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- if (type & LEFT)
- type &= ~ZEROPAD;
- if (base < 2 || base > 36)
+ oprom = finddevice("/openprom");
+ if (oprom == (phandle) -1)
return 0;
- c = (type & ZEROPAD) ? '0' : ' ';
- sign = 0;
- if (type & SIGN) {
- if ((signed long long)num < 0) {
- sign = '-';
- num = - (signed long long)num;
- size--;
- } else if (type & PLUS) {
- sign = '+';
- size--;
- } else if (type & SPACE) {
- sign = ' ';
- size--;
+ if (getprop(oprom, "model", version, sizeof(version)) <= 0)
+ return 0;
+ version[sizeof(version)-1] = 0;
+ printf("OF version = '%s'\r\n", version);
+ if (!string_match(version, "Open Firmware, 1.")
+ && !string_match(version, "FirmWorks,3."))
+ return 0;
+ chosen = finddevice("/chosen");
+ if (chosen == (phandle) -1) {
+ chosen = finddevice("/chosen@0");
+ if (chosen == (phandle) -1) {
+ printf("no chosen\n");
+ return 0;
}
}
- if (type & SPECIAL) {
- if (base == 16)
- size -= 2;
- else if (base == 8)
- size--;
- }
- i = 0;
- if (num == 0)