diff options
Diffstat (limited to 'qemu/roms/SLOF/clients/takeover')
-rw-r--r-- | qemu/roms/SLOF/clients/takeover/Makefile | 60 | ||||
-rw-r--r-- | qemu/roms/SLOF/clients/takeover/client.lds | 60 | ||||
-rw-r--r-- | qemu/roms/SLOF/clients/takeover/entry.S | 99 | ||||
-rw-r--r-- | qemu/roms/SLOF/clients/takeover/main.c | 163 | ||||
-rw-r--r-- | qemu/roms/SLOF/clients/takeover/ppc32wrap.S | 30 | ||||
-rw-r--r-- | qemu/roms/SLOF/clients/takeover/takeover.h | 23 | ||||
-rw-r--r-- | qemu/roms/SLOF/clients/takeover/takeover.oco | bin | 0 -> 3360 bytes |
7 files changed, 435 insertions, 0 deletions
diff --git a/qemu/roms/SLOF/clients/takeover/Makefile b/qemu/roms/SLOF/clients/takeover/Makefile new file mode 100644 index 000000000..f71f7ecdf --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/clients/takeover/client.lds b/qemu/roms/SLOF/clients/takeover/client.lds new file mode 100644 index 000000000..2701d8e1e --- /dev/null +++ b/qemu/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(8); + _got = .; + *(.got .toc) + _got_end = .; + } + .comment : { *(.comment) } + .branch_lt : { *(.branch_lt) } + .bss : + { + __bssStart = .; + *(*COM* .bss .gnu.linkonce.b.*) + __client_end = .; + __bssSize = . - __bssStart; + } +} diff --git a/qemu/roms/SLOF/clients/takeover/entry.S b/qemu/roms/SLOF/clients/takeover/entry.S new file mode 100644 index 000000000..a1030eb40 --- /dev/null +++ b/qemu/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+0x8000 +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/qemu/roms/SLOF/clients/takeover/main.c b/qemu/roms/SLOF/clients/takeover/main.c new file mode 100644 index 000000000..360d8eaed --- /dev/null +++ b/qemu/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 <ioctl.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", ®, 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/qemu/roms/SLOF/clients/takeover/ppc32wrap.S b/qemu/roms/SLOF/clients/takeover/ppc32wrap.S new file mode 100644 index 000000000..90afa268d --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/clients/takeover/takeover.h b/qemu/roms/SLOF/clients/takeover/takeover.h new file mode 100644 index 000000000..f348e2359 --- /dev/null +++ b/qemu/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/qemu/roms/SLOF/clients/takeover/takeover.oco b/qemu/roms/SLOF/clients/takeover/takeover.oco Binary files differnew file mode 100644 index 000000000..6e2a1a6ab --- /dev/null +++ b/qemu/roms/SLOF/clients/takeover/takeover.oco |