gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
                44x.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c
 src-plat := of.c cuboot-83xx.c cuboot-85xx.c holly.c \
-               cuboot-ebony.c treeboot-ebony.c prpmc2800.c
+               cuboot-ebony.c treeboot-ebony.c prpmc2800.c \
+               ps3-head.S ps3-hvcall.S ps3.c
 src-boot := $(src-wlib) $(src-plat) empty.c
 
 src-boot := $(addprefix $(obj)/, $(src-boot))
 $(obj)/empty.c:
        @touch $@
 
-$(obj)/zImage.lds $(obj)/zImage.coff.lds: $(obj)/%: $(srctree)/$(src)/%.S
+$(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds: $(obj)/%: $(srctree)/$(src)/%.S
        @cp $< $@
 
 clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \
-               empty.c zImage.coff.lds zImage.lds
+               empty.c zImage zImage.coff.lds zImage.ps3.lds zImage.lds
 
 quiet_cmd_bootcc = BOOTCC  $@
       cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $<
 
 targets                += $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a)
 extra-y                := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \
-                  $(obj)/zImage.lds $(obj)/zImage.coff.lds
+                  $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds
 
 wrapper                :=$(srctree)/$(src)/wrapper
 wrapperbits    := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree) \
 $(obj)/zImage.iseries: vmlinux
        $(STRIP) -s -R .comment $< -o $@
 
-$(obj)/zImage.ps3: vmlinux
-       $(STRIP) -s -R .comment $< -o $@
+$(obj)/zImage.ps3: vmlinux  $(wrapper) $(wrapperbits) $(srctree)/$(src)/dts/ps3.dts
+       $(STRIP) -s -R .comment $< -o vmlinux.strip
+       $(call cmd,wrap,ps3,$(srctree)/$(src)/dts/ps3.dts,,)
 
-$(obj)/zImage.initrd.ps3: vmlinux
-       @echo "  WARNING zImage.initrd.ps3 not supported (yet)"
+$(obj)/zImage.initrd.ps3: vmlinux  $(wrapper) $(wrapperbits) $(srctree)/$(src)/dts/ps3.dts $(obj)/ramdisk.image.gz
+       $(call cmd,wrap,ps3,$(srctree)/$(src)/dts/ps3.dts,,$(obj)/ramdisk.image.gz)
 
 $(obj)/uImage: vmlinux $(wrapperbits)
        $(call if_changed,wrap,uboot)
        sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $<
 
 # anything not in $(targets)
-clean-files += $(image-) $(initrd-) zImage zImage.initrd cuImage.* treeImage.*
+clean-files += $(image-) $(initrd-) zImage zImage.initrd cuImage.* treeImage.* \
+       otheros.bld
 
 # clean up files cached by wrapper
 clean-kernel := vmlinux.strip vmlinux.bin
 
--- /dev/null
+/*
+ *  PS3 bootwrapper entry.
+ *
+ *  Copyright (C) 2007 Sony Computer Entertainment Inc.
+ *  Copyright 2007 Sony Corp.
+ *
+ *  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; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "ppc_asm.h"
+
+       .text
+
+/*
+ * __system_reset_overlay - The PS3 first stage entry.
+ *
+ * The bootwraper build script copies the 0x100 bytes at symbol
+ * __system_reset_overlay to offset 0x100 of the rom image.
+ *
+ * The PS3 has a single processor with two threads.
+ */
+
+       .globl __system_reset_overlay
+__system_reset_overlay:
+
+       /* Switch to 32-bit mode. */
+
+       mfmsr   r9
+       clrldi  r9,r9,1
+       mtmsrd  r9
+       nop
+
+       /* Get thread number in r3 and branch. */
+
+       mfspr   r3, 0x88
+       cntlzw. r3, r3
+       li      r4, 0
+       li      r5, 0
+       beq     1f
+
+       /* Secondary goes to __secondary_hold in kernel. */
+
+       li      r4, 0x60
+       mtctr   r4
+       bctr
+
+       /* Primary delays then goes to _zimage_start in wrapper. */
+1:
+       or      31, 31, 31 /* db16cyc */
+       or      31, 31, 31 /* db16cyc */
+
+       lis     r4, _zimage_start@ha
+       addi    r4, r4, _zimage_start@l
+       mtctr   r4
+       bctr
+
+/*
+ * __system_reset_kernel - Place holder for the kernel reset vector.
+ *
+ * The bootwrapper build script copies 0x100 bytes from offset 0x100
+ * of the rom image to the symbol __system_reset_kernel.  At runtime
+ * the bootwrapper program copies the 0x100 bytes at __system_reset_kernel
+ * to ram address 0x100.  This symbol must occupy 0x100 bytes.
+ */
+
+       .globl __system_reset_kernel
+__system_reset_kernel:
+
+       . = __system_reset_kernel + 0x100
 
--- /dev/null
+/*
+ *  PS3 bootwrapper hvcalls.
+ *
+ *  Copyright (C) 2007 Sony Computer Entertainment Inc.
+ *  Copyright 2007 Sony Corp.
+ *
+ *  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; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "ppc_asm.h"
+
+/*
+ * The PS3 hypervisor uses a 64 bit "C" language calling convention.
+ * The routines here marshal arguments between the 32 bit wrapper
+ * program and the 64 bit hvcalls.
+ *
+ *  wrapper           lv1
+ *  32-bit (h,l)      64-bit
+ *
+ *  1: r3,r4          <-> r3
+ *  2: r5,r6          <-> r4
+ *  3: r7,r8          <-> r5
+ *  4: r9,r10         <-> r6
+ *  5: 8(r1),12(r1)   <-> r7
+ *  6: 16(r1),20(r1)  <-> r8
+ *  7: 24(r1),28(r1)  <-> r9
+ *  8: 32(r1),36(r1)  <-> r10
+ *
+ */
+
+.macro GLOBAL name
+       .section ".text"
+       .balign 4
+       .globl \name
+\name:
+.endm
+
+.macro NO_SUPPORT name
+       GLOBAL \name
+       b ps3_no_support
+.endm
+
+.macro HVCALL num
+       li r11, \num
+       .long 0x44000022
+       extsw r3, r3
+.endm
+
+.macro SAVE_LR offset=4
+       mflr r0
+       stw r0, \offset(r1)
+.endm
+
+.macro LOAD_LR offset=4
+       lwz r0, \offset(r1)
+       mtlr r0
+.endm
+
+.macro LOAD_64_REG target,high,low
+       sldi r11, \high, 32
+       or \target, r11, \low
+.endm
+
+.macro LOAD_64_STACK target,offset
+       ld \target, \offset(r1)
+.endm
+
+.macro LOAD_R3
+       LOAD_64_REG r3,r3,r4
+.endm
+
+.macro LOAD_R4
+       LOAD_64_REG r4,r5,r6
+.endm
+
+.macro LOAD_R5
+       LOAD_64_REG r5,r7,r8
+.endm
+
+.macro LOAD_R6
+       LOAD_64_REG r6,r9,r10
+.endm
+
+.macro LOAD_R7
+       LOAD_64_STACK r7,8
+.endm
+
+.macro LOAD_R8
+       LOAD_64_STACK r8,16
+.endm
+
+.macro LOAD_R9
+       LOAD_64_STACK r9,24
+.endm
+
+.macro LOAD_R10
+       LOAD_64_STACK r10,32
+.endm
+
+.macro LOAD_REGS_0
+       stwu 1,-16(1)
+       stw 3, 8(1)
+.endm
+
+.macro LOAD_REGS_5
+       LOAD_R3
+       LOAD_R4
+       LOAD_R5
+       LOAD_R6
+       LOAD_R7
+.endm
+
+.macro LOAD_REGS_6
+       LOAD_REGS_5
+       LOAD_R8
+.endm
+
+.macro LOAD_REGS_8
+       LOAD_REGS_6
+       LOAD_R9
+       LOAD_R10
+.endm
+
+.macro STORE_REGS_0_1
+       lwz r11, 8(r1)
+       std r4, 0(r11)
+       mr r4, r3
+       li r3, 0
+       addi r1,r1,16
+.endm
+
+.macro STORE_REGS_5_2
+       lwz r11, 16(r1)
+       std r4, 0(r11)
+       lwz r11, 24(r1)
+       std r5, 0(r11)
+.endm
+
+.macro STORE_REGS_6_1
+       lwz r11, 24(r1)
+       std r4, 0(r11)
+.endm
+
+GLOBAL lv1_get_logical_ppe_id
+       SAVE_LR
+       LOAD_REGS_0
+       HVCALL 69
+       STORE_REGS_0_1
+       LOAD_LR
+       blr
+
+GLOBAL lv1_get_logical_partition_id
+       SAVE_LR
+       LOAD_REGS_0
+       HVCALL 74
+       STORE_REGS_0_1
+       LOAD_LR
+       blr
+
+GLOBAL lv1_get_repository_node_value
+       SAVE_LR
+       LOAD_REGS_5
+       HVCALL 91
+       STORE_REGS_5_2
+       LOAD_LR
+       blr
+
+GLOBAL lv1_panic
+       SAVE_LR
+       LOAD_REGS_8
+       HVCALL 255
+       LOAD_LR
+       blr
 
--- /dev/null
+/*
+ *  PS3 bootwrapper support.
+ *
+ *  Copyright (C) 2007 Sony Computer Entertainment Inc.
+ *  Copyright 2007 Sony Corp.
+ *
+ *  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; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "elf.h"
+#include "string.h"
+#include "stdio.h"
+#include "page.h"
+#include "ops.h"
+
+extern s64 lv1_panic(u64 in_1);
+extern s64 lv1_get_logical_partition_id(u64 *out_1);
+extern s64 lv1_get_logical_ppe_id(u64 *out_1);
+extern s64 lv1_get_repository_node_value(u64 in_1, u64 in_2, u64 in_3,
+       u64 in_4, u64 in_5, u64 *out_1, u64 *out_2);
+
+#ifdef DEBUG
+#define DBG(fmt...) printf(fmt)
+#else
+static inline int __attribute__ ((format (printf, 1, 2))) DBG(
+       const char *fmt, ...) {return 0;}
+#endif
+
+BSS_STACK(4096);
+
+/* A buffer that may be edited by tools operating on a zImage binary so as to
+ * edit the command line passed to vmlinux (by setting /chosen/bootargs).
+ * The buffer is put in it's own section so that tools may locate it easier.
+ */
+static char cmdline[COMMAND_LINE_SIZE]
+       __attribute__((__section__("__builtin_cmdline")));
+
+static void prep_cmdline(void *chosen)
+{
+       if (cmdline[0] == '\0')
+               getprop(chosen, "bootargs", cmdline, COMMAND_LINE_SIZE-1);
+       else
+               setprop_str(chosen, "bootargs", cmdline);
+
+       printf("cmdline: '%s'\n", cmdline);
+}
+
+static void ps3_console_write(const char *buf, int len)
+{
+}
+
+static void ps3_exit(void)
+{
+       printf("ps3_exit\n");
+
+       /* lv1_panic will shutdown the lpar. */
+
+       lv1_panic(0); /* zero = do not reboot */
+       while (1);
+}
+
+static int ps3_repository_read_rm_size(u64 *rm_size)
+{
+       s64 result;
+       u64 lpar_id;
+       u64 ppe_id;
+       u64 v2;
+
+       result = lv1_get_logical_partition_id(&lpar_id);
+
+       if (result)
+               return -1;
+
+       result = lv1_get_logical_ppe_id(&ppe_id);
+
+       if (result)
+               return -1;
+
+       /*
+        * n1: 0000000062690000 : ....bi..
+        * n2: 7075000000000000 : pu......
+        * n3: 0000000000000001 : ........
+        * n4: 726d5f73697a6500 : rm_size.
+       */
+
+       result = lv1_get_repository_node_value(lpar_id, 0x0000000062690000ULL,
+               0x7075000000000000ULL, ppe_id, 0x726d5f73697a6500ULL, rm_size,
+               &v2);
+
+       printf("%s:%d: ppe_id  %lu \n", __func__, __LINE__,
+               (unsigned long)ppe_id);
+       printf("%s:%d: lpar_id %lu \n", __func__, __LINE__,
+               (unsigned long)lpar_id);
+       printf("%s:%d: rm_size %llxh \n", __func__, __LINE__, *rm_size);
+
+       return result ? -1 : 0;
+}
+
+void ps3_copy_vectors(void)
+{
+       extern char __system_reset_kernel[];
+
+       memcpy((void *)0x100, __system_reset_kernel, 0x100);
+       flush_cache((void *)0x100, 0x100);
+}
+
+void platform_init(void)
+{
+       extern char _end[];
+       extern char _dtb_start[];
+       extern char _initrd_start[];
+       extern char _initrd_end[];
+       const u32 heapsize = 0x1000000 - (u32)_end; /* 16MiB */
+       void *chosen;
+       unsigned long ft_addr;
+       u64 rm_size;
+
+       console_ops.write = ps3_console_write;
+       platform_ops.exit = ps3_exit;
+
+       printf("\n-- PS3 bootwrapper --\n");
+
+       simple_alloc_init(_end, heapsize, 32, 64);
+       ft_init(_dtb_start, 0, 4);
+
+       chosen = finddevice("/chosen");
+
+       ps3_repository_read_rm_size(&rm_size);
+       dt_fixup_memory(0, rm_size);
+
+       if (_initrd_end > _initrd_start) {
+               setprop_val(chosen, "linux,initrd-start", (u32)(_initrd_start));
+               setprop_val(chosen, "linux,initrd-end", (u32)(_initrd_end));
+       }
+
+       prep_cmdline(chosen);
+
+       ft_addr = dt_ops.finalize();
+
+       ps3_copy_vectors();
+
+       printf(" flat tree at 0x%lx\n\r", ft_addr);
+
+       ((kernel_entry_t)0)(ft_addr, 0, NULL);
+
+       ps3_exit();
+}
 
 cuboot*)
     gzip=
     ;;
+ps3)
+    platformo="$object/ps3-head.o $object/ps3-hvcall.o $object/ps3.o"
+    lds=$object/zImage.ps3.lds
+    gzip=
+    ext=bin
+    objflags="-O binary --set-section-flags=.bss=contents,alloc,load,data"
+    ksection=.kernel:vmlinux.bin
+    isection=.kernel:initrd
+    ;;
 esac
 
 vmz="$tmpdir/`basename \"$kernel\"`.$ext"
     fi
     exit 0
     ;;
+ps3)
+    # The ps3's loader supports loading gzipped binary images from flash
+    # rom to addr zero. The loader enters the image at addr 0x100.  A
+    # bootwrapper overlay is use to arrange for the kernel to be loaded
+    # to addr zero and to have a suitable bootwrapper entry at 0x100.
+    # To construct the rom image, 0x100 bytes from offset 0x100 in the
+    # kernel is copied to the bootwrapper symbol __system_reset_kernel.
+    # The 0x100 bytes at the bootwrapper symbol __system_reset_overlay is
+    # then copied to offset 0x100.  At runtime the bootwrapper program
+    # copies the 0x100 bytes at __system_reset_kernel to addr 0x100.
+
+    system_reset_overlay=0x`${CROSS}nm "$ofile" \
+        | grep ' __system_reset_overlay$'       \
+        | cut -d' ' -f1`
+    system_reset_overlay=`printf "%d" $system_reset_overlay`
+    system_reset_kernel=0x`${CROSS}nm "$ofile" \
+        | grep ' __system_reset_kernel$'       \
+        | cut -d' ' -f1`
+    system_reset_kernel=`printf "%d" $system_reset_kernel`
+    overlay_dest="256"
+    overlay_size="256"
+
+    rm -f "$object/otheros.bld"
+
+    ${CROSS}objcopy -O binary "$ofile" "$ofile.bin"
+
+    msg=$(dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
+        skip=$overlay_dest seek=$system_reset_kernel      \
+        count=$overlay_size bs=1 2>&1)
+
+    if [ $? -ne "0" ]; then
+       echo $msg
+       exit 1
+    fi
+
+    msg=$(dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
+        skip=$system_reset_overlay seek=$overlay_dest     \
+        count=$overlay_size bs=1 2>&1)
+
+    if [ $? -ne "0" ]; then
+       echo $msg
+       exit 2
+    fi
+
+    gzip --force -9 --stdout "$ofile.bin" > "$object/otheros.bld"
+    ;;
 esac
 
--- /dev/null
+OUTPUT_ARCH(powerpc:common)
+ENTRY(_zimage_start)
+EXTERN(_zimage_start)
+SECTIONS
+{
+  _vmlinux_start =  .;
+  .kernel:vmlinux.bin : { *(.kernel:vmlinux.bin) }
+  _vmlinux_end =  .;
+
+  . = ALIGN(4096);
+  _dtb_start = .;
+  .kernel:dtb : { *(.kernel:dtb) }
+  _dtb_end = .;
+
+  . = ALIGN(4096);
+  _initrd_start =  .;
+  .kernel:initrd : { *(.kernel:initrd) }
+  _initrd_end =  .;
+
+  _start = .;
+  .text      :
+  {
+    *(.text)
+    *(.fixup)
+  }
+  _etext = .;
+  . = ALIGN(4096);
+  .data    :
+  {
+    *(.rodata*)
+    *(.data*)
+    *(.sdata*)
+    __got2_start = .;
+    *(.got2)
+    __got2_end = .;
+  }
+
+  . = ALIGN(4096);
+  _edata  =  .;
+
+  . = ALIGN(4096);
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss)
+   *(.bss)
+  }
+  . = ALIGN(4096);
+  _end = . ;
+}
 
        BUG_ON(map.rm.base);
        BUG_ON(!map.rm.size);
 
-       lmb_add(map.rm.base, map.rm.size);
-       lmb_analyze();
 
        /* arrange to do this in ps3_mm_add_memory */
        ps3_mm_region_create(&map.r1, map.total - map.rm.size);