summaryrefslogtreecommitdiffstats
path: root/src/roms/SLOF/clients/takeover
diff options
context:
space:
mode:
Diffstat (limited to 'src/roms/SLOF/clients/takeover')
-rw-r--r--src/roms/SLOF/clients/takeover/Makefile60
-rw-r--r--src/roms/SLOF/clients/takeover/client.lds60
-rw-r--r--src/roms/SLOF/clients/takeover/entry.S99
-rw-r--r--src/roms/SLOF/clients/takeover/main.c163
-rw-r--r--src/roms/SLOF/clients/takeover/ppc32wrap.S30
-rw-r--r--src/roms/SLOF/clients/takeover/takeover.h23
-rw-r--r--src/roms/SLOF/clients/takeover/takeover.ocobin0 -> 3360 bytes
7 files changed, 435 insertions, 0 deletions
diff --git a/src/roms/SLOF/clients/takeover/Makefile b/src/roms/SLOF/clients/takeover/Makefile
new file mode 100644
index 0000000..f71f7ec
--- /dev/null
+++ b/src/roms/SLOF/clients/takeover/Makefile
@@ -0,0 +1,60 @@
+# *****************************************************************************
+# * Copyright (c) 2004, 2011 IBM Corporation
+# * All rights reserved.
+# * This program and the accompanying materials
+# * are made available under the terms of the BSD License
+# * which accompanies this distribution, and is available at
+# * http://www.opensource.org/licenses/bsd-license.php
+# *
+# * Contributors:
+# * IBM Corporation - initial implementation
+# ****************************************************************************/
+
+include $(TOPCMNDIR)/make.rules
+
+SNKDIR = $(TOPCMNDIR)/clients/net-snk
+
+CFLAGS += -fno-builtin -I$(LIBCMNDIR)/libc/include
+CFLAGS += -I$(SNKDIR)/include -I. $(CPUARCHDEF)
+CFLAGS += -I$(INCLBRDDIR) -I$(INCLCMNDIR) -I$(INCLCMNDIR)/$(CPUARCH)
+CFLAGS += -O2 -msoft-float -Wa,-mregnames $(RELEASE)
+
+OBJS = $(SNKDIR)/kernel/kernel.o
+OBJS += $(SNKDIR)/oflib/oflib.o
+OBJS += $(SNKDIR)/libc/time/timer.o
+OBJS += entry.o main.o of.elf takeover.o
+OBJS += $(LIBCMNDIR)/libelf.a $(LIBCMNDIR)/libc.a
+
+%.o: %.S
+ $(CC) $(CFLAGS) -c $^
+
+all: takeover.elf
+
+takeover.elf: ppc32wrap.o takeover.elf32
+ @echo " ====== Building $@ ======"
+ $(LD) -N -melf32ppclinux -static -nostdlib \
+ -Ttext=0x400000 -Tdata=0x400100 \
+ $(LDFLAGS) $^ -o $@
+
+takeover.elf64: entry.o main.o takeover.o $(SNKDIR)/libc/time/timer.o of.elf
+ $(MAKE) -C $(LIBCMNDIR) libc
+ $(MAKE) -C $(CLIENTSDIR)
+ $(LD) $(LDFLAGS) -o $@ -Tclient.lds $(OBJS)
+
+of.elf: ../../boot_rom.bin
+ $(OBJCOPY) --input-target=binary --binary-architecture=powerpc -O elf64-powerpc $< $@
+
+takeover.elf32: takeover.elf64
+ $(OBJCOPY) -O binary $^ takeover.tmp
+ $(OBJCOPY) --input-target=binary --binary-architecture=powerpc -O elf32-powerpc takeover.tmp $@
+
+ppc32wrap.o: ppc32wrap.S
+ $(CROSS)gcc -m32 $(CFLAGS) -c $< -o $@
+
+clean distclean:
+ $(MAKE) -C $(LIBCMNDIR) $@
+ $(MAKE) -C $(CLIENTSDIR) $@
+ $(RM) *.o *.bin *.elf
+ $(RM) takeover.elf32 takeover.elf64 takeover.tmp
+%.o: %.oco
+ cp -f $< $@
diff --git a/src/roms/SLOF/clients/takeover/client.lds b/src/roms/SLOF/clients/takeover/client.lds
new file mode 100644
index 0000000..0ab428a
--- /dev/null
+++ b/src/roms/SLOF/clients/takeover/client.lds
@@ -0,0 +1,60 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+OUTPUT_FORMAT("elf64-powerpc", "elf64-powerpc", "elf64-powerpc")
+OUTPUT_ARCH(powerpc:common64)
+ENTRY(_entry)
+
+SECTIONS {
+ .client 0x400100:
+ {
+ __client_start = .;
+ *(.start)
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ *(.sfpr .glink)
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ KEEP (*(.opd))
+ . = ALIGN(256);
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(256);
+ } =0x60000000
+
+ .diag_table :
+ {
+ _diag_init_start = .;
+ *(.diag_init)
+ _diag_init_end = .;
+ }
+ .lowmem :
+ {
+ _lowmem_start = .;
+ *(.lowmem)
+ _lowmem_end = .;
+ }
+
+ .got :
+ {
+ . = ALIGN(256);
+ _got = DEFINED (.TOC.) ? .TOC. : ADDR (.got) + 0x8000;
+ *(.got .toc)
+ _got_end = .;
+ }
+ .comment : { *(.comment) }
+ .branch_lt : { *(.branch_lt) }
+ .bss :
+ {
+ __bssStart = .;
+ *(*COM* .bss .gnu.linkonce.b.*)
+ __client_end = .;
+ __bssSize = . - __bssStart;
+ }
+}
diff --git a/src/roms/SLOF/clients/takeover/entry.S b/src/roms/SLOF/clients/takeover/entry.S
new file mode 100644
index 0000000..ff48273
--- /dev/null
+++ b/src/roms/SLOF/clients/takeover/entry.S
@@ -0,0 +1,99 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+#include <macros.h>
+#include "takeover.h"
+
+ .globl _wrapclient
+ .section ".start"
+ .align 3
+
+_wrapclient:
+ bcl 20,31,over # branch after pointer table
+base:
+ .align 3
+.LCgot: .quad _got-base
+over:
+ mflr r8 # gpr 8 is the base
+ ld r2, .LCgot-base(r8) # load got pointer
+ add r2, r2, r8 # add base
+ li 14, 0
+ oris 14, 14, __bssSize@h
+ ori 14, 14, __bssSize@l
+ addi 14,14,7
+ srwi 14,14,3
+ mtctr 14
+ li 14, 0
+ oris 14, 14, __bssStart@h
+ ori 14, 14, __bssStart@l
+ subi 14, 14, 8
+ li 15, 0
+1:
+ stdu 15,8(14)
+ bdnz 1b
+
+ bl ._entry
+
+
+
+ .globl slaveLoopNoTakeover
+slaveLoopNoTakeover:
+ mr 28,3
+
+ li 14,0
+ oris 14, 14, slaveQuitt@h
+ ori 14, 14, slaveQuitt@l
+
+ li 3,0
+ std 3,0(14)
+1:
+ ld 3,0(14)
+ cmpld 3,28
+ bne 1b
+
+ li 3,0
+ std 3,0(14)
+
+ LOAD64(r3, (TAKEOVERBASEADDRESS+0x150))
+ mtctr r3
+ bctr
+
+
+ .globl slaveLoop
+slaveLoop:
+ mr 28,3
+ li r3, 0x5124
+ li r0, -1; .long 0x44000022
+
+ li 14,0
+ oris 14, 14, slaveQuitt@h
+ ori 14, 14, slaveQuitt@l
+ li 3,0
+ std 3,0(14)
+1:
+ ld 3,0(14)
+ cmpld 3,28
+ bne 1b
+
+ li 3,0
+ std 3,0(14)
+
+ LOAD64(r3, (TAKEOVERBASEADDRESS+0x150))
+ mtctr r3
+ bctr
+
+
+C_ENTRY(m_sync)
+ isync
+ sync
+ nop
+ blr
diff --git a/src/roms/SLOF/clients/takeover/main.c b/src/roms/SLOF/clients/takeover/main.c
new file mode 100644
index 0000000..1e1b026
--- /dev/null
+++ b/src/roms/SLOF/clients/takeover/main.c
@@ -0,0 +1,163 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <of.h>
+#include <pci.h>
+#include <cpu.h>
+#include <unistd.h>
+#include <takeover.h>
+
+extern void call_client_interface(of_arg_t *);
+extern void m_sync(void);
+
+int callback(int argc, char *argv[]);
+
+#define boot_rom_bin_start _binary_______boot_rom_bin_start
+#define boot_rom_bin_end _binary_______boot_rom_bin_end
+
+extern char boot_rom_bin_start;
+extern char boot_rom_bin_end;
+
+#if defined(__GNUC__)
+# define UNUSED __attribute__((unused))
+#else
+# define UNUSED
+#endif
+
+void *
+sbrk(int incr)
+{
+ return (void *) -1;
+}
+
+static void
+doWait(void)
+{
+ static const char *wheel = "|/-\\";
+ static int i = 0;
+ volatile int dly = 0xf0000;
+ while (dly--)
+ asm volatile (" nop ");
+ printf("\b%c", wheel[i++]);
+ i &= 0x3;
+}
+
+static void
+quiesce(void)
+{
+ of_arg_t arg = {
+ p32cast "quiesce",
+ 0, 0,
+ };
+ call_client_interface(&arg);
+}
+
+static int
+startCpu(int num, int addr, int reg)
+{
+ of_arg_t arg = {
+ p32cast "start-cpu",
+ 3, 0,
+ {num, addr, reg}
+ };
+ call_client_interface(&arg);
+ return arg.args[3];
+}
+
+volatile unsigned long slaveQuitt;
+int takeoverFlag;
+
+void
+main(int argc, char *argv[])
+{
+ phandle_t cpus;
+ phandle_t cpu;
+ unsigned long slaveMask;
+ extern int slaveLoop[];
+ extern int slaveLoopNoTakeover[];
+ int index = 0;
+ int delay = 100;
+ unsigned long reg;
+ unsigned long msr;
+
+ asm volatile ("mfmsr %0":"=r" (msr));
+ if (msr & 0x1000000000000000)
+ takeoverFlag = 0;
+ else
+ takeoverFlag = 1;
+
+ cpus = of_finddevice("/cpus");
+ cpu = of_child(cpus);
+ slaveMask = 0;
+ while (cpu) {
+ char devType[100];
+ *devType = '\0';
+ of_getprop(cpu, "device_type", devType, sizeof(devType));
+ if (strcmp(devType, "cpu") == 0) {
+ of_getprop(cpu, "reg", &reg, sizeof(reg));
+ if (index) {
+ printf("\r\n takeover on cpu%d (%x, %lx) ", index,
+ cpu, reg);
+ slaveQuitt = -1;
+ if (takeoverFlag)
+ startCpu(cpu, (int)(unsigned long)slaveLoop, index);
+ else
+ startCpu(cpu, (int)(unsigned long)slaveLoopNoTakeover,
+ index);
+ slaveMask |= 0x1 << index;
+ delay = 100;
+ while (delay-- && slaveQuitt)
+ doWait();
+ }
+ index++;
+ }
+ cpu = of_peer(cpu);
+ }
+
+
+ printf("\r\n takeover on master cpu ");
+ quiesce();
+
+ delay = 5;
+ while (delay--)
+ doWait();
+ if (takeoverFlag)
+ takeover();
+
+ memcpy((void*)TAKEOVERBASEADDRESS, &boot_rom_bin_start, &boot_rom_bin_end - &boot_rom_bin_start);
+ flush_cache((void *)TAKEOVERBASEADDRESS, &boot_rom_bin_end - &boot_rom_bin_start);
+ index = 0;
+
+ while (slaveMask) {
+ m_sync();
+ unsigned long shifter = 0x1 << index;
+ if (shifter & slaveMask) {
+ slaveQuitt = index;
+ while (slaveQuitt)
+ m_sync();
+ slaveMask &= ~shifter;
+ }
+ index++;
+ }
+
+ asm volatile(" mtctr %0 ; bctr " : : "r" (TAKEOVERBASEADDRESS+0x180) );
+}
+
+int
+callback(int argc, char *argv[])
+{
+ /* Dummy, only for takeover */
+ return (0);
+}
diff --git a/src/roms/SLOF/clients/takeover/ppc32wrap.S b/src/roms/SLOF/clients/takeover/ppc32wrap.S
new file mode 100644
index 0000000..90afa26
--- /dev/null
+++ b/src/roms/SLOF/clients/takeover/ppc32wrap.S
@@ -0,0 +1,30 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+ .globl _start
+ .section ".text"
+ .align 3
+
+_start:
+ nop
+ bl over
+ .llong 0x9000000000003000
+over:
+ li 14, 0
+ oris 14, 14, _binary_takeover_tmp_start@h
+ ori 14, 14, _binary_takeover_tmp_start@l
+ mtsrr0 14
+ mflr 15
+ ld 14,0(15)
+ mtsrr1 14
+ rfid
+
diff --git a/src/roms/SLOF/clients/takeover/takeover.h b/src/roms/SLOF/clients/takeover/takeover.h
new file mode 100644
index 0000000..f348e23
--- /dev/null
+++ b/src/roms/SLOF/clients/takeover/takeover.h
@@ -0,0 +1,23 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+#if defined(CPU_CBEA)
+#define TAKEOVERBASEADDRESS 0x0e000000
+#elif defined(CPU_PPC970)
+#define TAKEOVERBASEADDRESS 0x00000000
+#else
+#error no processor specified
+#endif
+
+#ifndef __ASSEMBLER__
+int takeover(void);
+#endif
diff --git a/src/roms/SLOF/clients/takeover/takeover.oco b/src/roms/SLOF/clients/takeover/takeover.oco
new file mode 100644
index 0000000..6e2a1a6
--- /dev/null
+++ b/src/roms/SLOF/clients/takeover/takeover.oco
Binary files differ
OpenPOWER on IntegriCloud