summaryrefslogtreecommitdiffstats
path: root/qemu/roms/SLOF/board-qemu/llfw
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/SLOF/board-qemu/llfw')
-rw-r--r--qemu/roms/SLOF/board-qemu/llfw/Cboot.S18
-rw-r--r--qemu/roms/SLOF/board-qemu/llfw/Makefile59
-rw-r--r--qemu/roms/SLOF/board-qemu/llfw/board_io.S46
-rw-r--r--qemu/roms/SLOF/board-qemu/llfw/stage2.c205
-rw-r--r--qemu/roms/SLOF/board-qemu/llfw/stage2.h23
-rw-r--r--qemu/roms/SLOF/board-qemu/llfw/stage2.lds59
-rw-r--r--qemu/roms/SLOF/board-qemu/llfw/stage2_head.S95
-rw-r--r--qemu/roms/SLOF/board-qemu/llfw/startup.S240
-rw-r--r--qemu/roms/SLOF/board-qemu/llfw/version.S42
9 files changed, 787 insertions, 0 deletions
diff --git a/qemu/roms/SLOF/board-qemu/llfw/Cboot.S b/qemu/roms/SLOF/board-qemu/llfw/Cboot.S
new file mode 100644
index 000000000..d22f3c934
--- /dev/null
+++ b/qemu/roms/SLOF/board-qemu/llfw/Cboot.S
@@ -0,0 +1,18 @@
+/******************************************************************************
+ * 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
+ *****************************************************************************/
+
+ .org 0
+
+ /* Boot Information, hardcoded to ColdReset */
+ .quad 1
+ /* start address */
+ .quad 0x100
diff --git a/qemu/roms/SLOF/board-qemu/llfw/Makefile b/qemu/roms/SLOF/board-qemu/llfw/Makefile
new file mode 100644
index 000000000..c83f21e3a
--- /dev/null
+++ b/qemu/roms/SLOF/board-qemu/llfw/Makefile
@@ -0,0 +1,59 @@
+# *****************************************************************************
+# * 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 ../../make.rules
+
+CPPFLAGS = -I$(INCLBRDDIR) -I$(INCLCMNDIR) -I$(INCLCMNDIR)/$(CPUARCH) \
+ -I$(LIBCMNDIR)/libc/include
+CFLAGS += -fno-builtin $(FLAG) $(CPPFLAGS) -O2 -msoft-float $(MAMBO)
+CFLAGS += $(BOOT) $(IOCONF) -Wa,-mregnames $(RELEASE) $(CPUARCHDEF) -Wall
+ASFLAGS = $(BOOT) $(IOCONF) $(RELEASE)$(CPUARCHDEF) -Wa,-mregnames
+LDFLAGS1 = -nostdlib -e__start -Tstage2.lds -N -Ttext=0x100
+
+
+STG1OBJ = startup.o version.o boot_abort.o romfs.o io_generic.o board_io.o
+STG1OBJ += stage2_head.o stage2.o comlib.o romfs_wrap.o nvramlog.o
+
+.PHONY: version.S
+
+all: stage1.bin Cboot.o
+
+stage1.bin: $(STG1OBJ) $(LIBCMNDIR)/libelf.a $(LIBCMNDIR)/libc.a \
+ $(LIBCMNDIR)/libhvcall.a
+ $(LD) $(LDFLAGS1) -o stage1.elf $^
+ $(OBJCOPY) -O binary stage1.elf $@
+
+romfs.o: ../../llfw/romfs.S
+ $(CC) $(CFLAGS) -c ../../llfw/romfs.S
+
+boot_abort.o: ../../llfw/boot_abort.S
+ $(CC) $(CFLAGS) -c ../../llfw/boot_abort.S
+
+nvramlog.o: ../../llfw/nvramlog.S
+ $(CC) $(CFLAGS) -c ../../llfw/nvramlog.S
+
+include $(LLFWCMNDIR)/clib/Makefile.inc
+
+include $(LLFWCMNDIR)/io_generic/Makefile.inc
+
+romfs_wrap.o: ../../llfw/romfs_wrap.c
+ $(CC) $(CFLAGS) -c ../../llfw/romfs_wrap.c
+
+Cboot.o: Cboot.S
+ $(CC) $(CFLAGS) -c $^
+ $(OBJCOPY) -O binary Cboot.o Cboot.bin
+
+%.o: %.S
+ $(CC) $(CFLAGS) -c $^
+
+clean:
+ rm -f *.o *.bin *.elf
diff --git a/qemu/roms/SLOF/board-qemu/llfw/board_io.S b/qemu/roms/SLOF/board-qemu/llfw/board_io.S
new file mode 100644
index 000000000..7d572ab18
--- /dev/null
+++ b/qemu/roms/SLOF/board-qemu/llfw/board_io.S
@@ -0,0 +1,46 @@
+/******************************************************************************
+ * 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 <macros.h>
+#include <cpu.h>
+
+ .text
+
+/****************************************************************************
+ * prints one character to serial console
+ *
+ * Input:
+ * R3 - character
+ *
+ * Returns: -
+ *
+ * Modifies Registers:
+ * R3, R4, R5, R6, R7
+ ****************************************************************************/
+ENTRY(io_putchar)
+ sldi r6,r3,(24+32)
+ li r3,0x58
+ li r4,0
+ li r5,1
+ .long 0x44000022
+ blr
+
+ENTRY(io_getchar)
+ mr r10,r3
+ li r3,0x54
+ li r4,0
+ .long 0x44000022
+ mr. r3,r4
+ beq 1f
+ srdi r3,r5,(24+32)
+ stb r3,0(r10)
+1: blr
diff --git a/qemu/roms/SLOF/board-qemu/llfw/stage2.c b/qemu/roms/SLOF/board-qemu/llfw/stage2.c
new file mode 100644
index 000000000..ef6ea355a
--- /dev/null
+++ b/qemu/roms/SLOF/board-qemu/llfw/stage2.c
@@ -0,0 +1,205 @@
+/******************************************************************************
+ * 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 <stdint.h>
+#include <xvect.h>
+#include <hw.h>
+#include <stdio.h>
+#include <romfs.h>
+#include "memmap.h"
+#include "stage2.h"
+#include <termctrl.h>
+#include "product.h"
+#include "calculatecrc.h"
+#include <cpu.h>
+#include <libelf.h>
+#include <string.h>
+#include "../lib/libhvcall/libhvcall.h"
+
+#define DEBUG(fmt...)
+//#define DEBUG(fmt...) printf(fmt)
+
+uint64_t gVecNum;
+
+uint64_t exception_stack_frame;
+
+typedef void (*pInterruptFunc_t) (void);
+
+pInterruptFunc_t vectorTable[0x2E << 1];
+
+extern void proceedInterrupt(void);
+
+/* Prototypes for functions of this file */
+void c_interrupt(uint64_t vecNum);
+void set_exceptionVector(int num, void *func);
+void early_c_entry(uint64_t start_addr, uint64_t fdt_addr);
+
+
+static void exception_forward(void)
+{
+ uint64_t val;
+
+ if (*(uint64_t *) XVECT_M_HANDLER) {
+ proceedInterrupt();
+ }
+
+ printf("\r\n exception %llx ", gVecNum);
+ asm volatile ("mfsrr0 %0":"=r" (val):);
+ printf("\r\nSRR0 = %08llx%08llx ", val >> 32, val);
+ asm volatile ("mfsrr1 %0":"=r" (val):);
+ printf(" SRR1 = %08llx%08llx ", val >> 32, val);
+
+ asm volatile ("mfsprg %0,2":"=r" (val):);
+ printf("\r\nSPRG2 = %08llx%08llx ", val >> 32, val);
+ asm volatile ("mfsprg %0,3":"=r" (val):);
+ printf(" SPRG3 = %08llx%08llx \r\n", val >> 32, val);
+ while (1);
+}
+
+void c_interrupt(uint64_t vecNum)
+{
+ gVecNum = vecNum;
+ if (vectorTable[vecNum >> 7]) {
+ vectorTable[vecNum >> 7] ();
+ } else {
+ exception_forward();
+ }
+}
+
+void set_exceptionVector(int num, void *func)
+{
+ vectorTable[num >> 7] = (pInterruptFunc_t) func;
+}
+
+static void load_file(uint64_t destAddr, char *name, uint64_t maxSize,
+ uint64_t romfs_base)
+{
+ uint64_t cnt;
+ struct romfs_lookup_t fileInfo;
+ int rc;
+
+ rc = c_romfs_lookup(name, romfs_base, &fileInfo);
+ if (rc) {
+ printf("Cannot find romfs file %s\n", name);
+ return;
+ }
+ DEBUG("Found romfs file %s\n", name);
+ if (maxSize) {
+ cnt = maxSize;
+ } else {
+ cnt = fileInfo.size_data;
+ }
+ memcpy((void *)destAddr, (void *)fileInfo.addr_data, cnt);
+ flush_cache((void *) destAddr, fileInfo.size_data);
+}
+
+extern void print_version(void);
+
+/***************************************************************************
+ * Function: early_c_entry
+ * Input : start_addr
+ *
+ * Description:
+ **************************************************************************/
+void early_c_entry(uint64_t start_addr, uint64_t fdt_addr)
+{
+ struct romfs_lookup_t fileInfo;
+ void (*ofw_start) (uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
+ uint64_t *boot_info;
+ uint64_t romfs_base, paflof_base;
+ // romfs header values
+ // struct stH *header = (struct stH *) (start_addr + 0x28);
+ // uint64_t flashlen = header->flashlen;
+ unsigned long ofw_addr[2];
+ int rc;
+ extern char __executable_start;
+ extern char __etext;
+
+ /*
+ * If we run on a broken environment, we need to patch our own sc 1
+ * calls to be able to trap hypercalls. This does not cover RTAS or
+ * any payload we will load yet.
+ */
+ if (patch_broken_sc1(&__executable_start, &__etext, NULL)) {
+ /* We are running in PR KVM on top of pHyp. Print all output
+ we missed to print so far again to fake identical behavior */
+ printf("\n\r\nSLOF");
+ print_version();
+ }
+
+ if (fdt_addr == 0) {
+ puts("ERROR: Flatten device tree not available!");
+ }
+
+ /* Hack: Determine base for "ROM filesystem" in memory...
+ * QEMU loads the FDT at the top of the available RAM, so we place
+ * the ROMFS just underneath. */
+ romfs_base = (fdt_addr - 0x410000) & ~0xffffLL;
+ memcpy((char *)romfs_base, 0, 0x400000);
+
+ exception_stack_frame = 0;
+
+ printf(" Press \"s\" to enter Open Firmware.\r\n\r\n");
+
+ DEBUG(" [c_romfs_lookup at %p]\n", c_romfs_lookup);
+ rc = c_romfs_lookup("bootinfo", romfs_base, &fileInfo);
+ if (rc)
+ printf(" !!! roomfs lookup(bootinfo) = %d\n", rc);
+ boot_info = (uint64_t *) fileInfo.addr_data;
+ boot_info[1] = start_addr;
+ load_file(0x100, "xvect", 0, romfs_base);
+ rc = c_romfs_lookup("ofw_main", romfs_base, &fileInfo);
+ if (rc)
+ printf(" !!! roomfs lookup(bootinfo) = %d\n", rc);
+
+ DEBUG(" [ofw_main addr hdr 0x%lx]\n", fileInfo.addr_header);
+ DEBUG(" [ofw_main addr data 0x%lx]\n", fileInfo.addr_data);
+ DEBUG(" [ofw_main size data 0x%lx]\n", fileInfo.size_data);
+ DEBUG(" [ofw_main flags 0x%lx]\n", fileInfo.flags);
+ DEBUG(" [hdr: 0x%08lx 0x%08lx]\n [ 0x%08lx 0x%08lx]\n",
+ ((uint64_t *)fileInfo.addr_header)[0],
+ ((uint64_t *)fileInfo.addr_header)[1],
+ ((uint64_t *)fileInfo.addr_header)[2],
+ ((uint64_t *)fileInfo.addr_header)[3]);
+
+ /* Assume that paflof and SNK need ca. 31 MiB RAM right now.
+ * TODO: Use value from ELF file instead */
+ paflof_base = romfs_base - 0x1F00000 + 0x100;
+ if ((int64_t)paflof_base <= 0LL) {
+ puts("ERROR: Not enough memory for Open Firmware");
+ }
+ rc = elf_load_file_to_addr((void *)fileInfo.addr_data, (void*)paflof_base,
+ ofw_addr, NULL, flush_cache);
+ DEBUG(" [load_elf_file returned %d]\n", rc);
+
+ ofw_start =
+ (void (*)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t))
+ &ofw_addr;
+ // re-enable the cursor
+ printf("%s%s", TERM_CTRL_RESET, TERM_CTRL_CRSON);
+ DEBUG(" [ofw_start=%p ofw_addr=0x%lx]\n", ofw_start, ofw_addr[0]);
+ ofw_addr[1] = ofw_addr[0];
+ /* Call the Open Firmware layer with ePAPR-style calling conventions:
+ * r3 = R3 Effective address of the device tree image. Note: this
+ * address must be 8-byte aligned in memory.
+ * r4 = implementation dependent, we use it for ROMFS base address
+ * r5 = 0
+ * r6 = 0x65504150 -- ePAPR magic value-to distinguish from
+ * non-ePAPR-compliant firmware
+ * r7 = size of Initially Mapped Area
+ * (right now we assume everything from 0 to the FDT is the IMA)
+ */
+ asm volatile("isync; sync;" : : : "memory");
+ ofw_start(fdt_addr, romfs_base, 0, 0x65504150, fdt_addr);
+ asm volatile("isync; sync;" : : : "memory");
+ // never return
+}
diff --git a/qemu/roms/SLOF/board-qemu/llfw/stage2.h b/qemu/roms/SLOF/board-qemu/llfw/stage2.h
new file mode 100644
index 000000000..9ce3c8203
--- /dev/null
+++ b/qemu/roms/SLOF/board-qemu/llfw/stage2.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
+ *****************************************************************************/
+
+#ifndef __STAGE2_H
+#define __STAGE2_H
+
+#ifndef __ASSEMBLER__
+
+#include <stddef.h>
+
+void u4memInit(void);
+
+#endif /* __ASSEMBLER__ */
+#endif /* __STAGE2_H */
diff --git a/qemu/roms/SLOF/board-qemu/llfw/stage2.lds b/qemu/roms/SLOF/board-qemu/llfw/stage2.lds
new file mode 100644
index 000000000..e060dd189
--- /dev/null
+++ b/qemu/roms/SLOF/board-qemu/llfw/stage2.lds
@@ -0,0 +1,59 @@
+/******************************************************************************
+ * 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)
+
+/* set the entry point */
+ENTRY ( __start )
+
+SECTIONS {
+ __executable_start = .;
+
+ .text : {
+ *(.text)
+ }
+
+ __etext = .;
+
+ . = ALIGN(8);
+
+ .data : {
+ *(.data)
+ *(.rodata .rodata.*)
+ *(.got1)
+ *(.sdata)
+ *(.opd)
+ }
+
+ /* FIXME bss at end ??? */
+
+ . = ALIGN(8);
+ __bss_start = .;
+ .bss : {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ }
+
+ . = ALIGN(8);
+ __bss_end = .;
+ __bss_size = (__bss_end - __bss_start);
+
+ __toc_start = .;
+ .got :
+ {
+ *(.toc .got)
+ }
+ . = ALIGN(8);
+ __toc_end = .;
+}
diff --git a/qemu/roms/SLOF/board-qemu/llfw/stage2_head.S b/qemu/roms/SLOF/board-qemu/llfw/stage2_head.S
new file mode 100644
index 000000000..c56b117ce
--- /dev/null
+++ b/qemu/roms/SLOF/board-qemu/llfw/stage2_head.S
@@ -0,0 +1,95 @@
+/******************************************************************************
+ * 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 "macros.h"
+#include "../../llfw/boot_abort.h"
+
+/*#################### defines #####################*/
+#define STACK_SIZE 0x4000
+
+/*#################### code ########################*/
+ .text
+ .globl .gluon_c_entry
+ .globl __toc_start
+ .globl __toc_end
+ .globl __bss_start
+ .globl __bss_size
+ .globl __start
+
+ASM_ENTRY(__startC)
+ /* clear out bss section */
+ LOAD64(r3, (__bss_start - 8))
+ LOAD64(r4, __bss_size)
+
+ /* divide __bss_size by 8 to get number */
+ /* of dwords to clear */
+ srwi. r4, r4, 3
+ beq bsscdone
+ li r5, 0
+ mtctr r4
+bssc: stdu r5, 8(r3)
+ bdnz bssc
+bsscdone:
+ /* setup stack */
+ LOAD64(r1, __stack_end + STACK_SIZE)
+
+ /* save return address beside stack */
+ addi r3, r1, 128
+ mflr r0
+ std r0, 0(r3)
+
+ /* setup toc */
+ bl toc_init
+
+ /* ------------------------------------ */
+ /* jump to c-code */
+ /* r31 = fdt - r5 */
+ /* ------------------------------------ */
+ li r3, r0
+ mr r4, r31
+ bl .early_c_entry
+
+ /* return to caller... */
+ LOAD64(r1, __stack_end + STACK_SIZE)
+ addi r1, r1, 128
+ ld r3, 0(r1)
+ mtlr r3
+ blr
+
+ /* #################################### */
+ /* Basic Additional Functions */
+ /* for extended lib functions see */
+ /* external library */
+ /* #################################### */
+ .align 2
+
+ /* ------------------------------------ */
+ /* updates toc in r2 */
+ /* ------------------------------------ */
+ASM_ENTRY(toc_init)
+ LOAD64(r2, __toc_start)
+ addi r2,r2,0x4000
+ addi r2,r2,0x4000
+ blr
+
+ /* ------------------------------------ */
+ /* stores arg#1 in r27 and stops */
+ /* ------------------------------------ */
+ENTRY(do_panic)
+ENTRY(halt_sys)
+ BOOT_ABORT_R3HINT(ABORT_CANIO, ALTBOOT, msg_e_ierror);
+
+ .section ".bss"
+ .balign STACK_SIZE
+__stack_end:
+ .space STACK_SIZE
+ .text
diff --git a/qemu/roms/SLOF/board-qemu/llfw/startup.S b/qemu/roms/SLOF/board-qemu/llfw/startup.S
new file mode 100644
index 000000000..bbd3ce3ac
--- /dev/null
+++ b/qemu/roms/SLOF/board-qemu/llfw/startup.S
@@ -0,0 +1,240 @@
+/******************************************************************************
+ * 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
+ *****************************************************************************/
+
+/* SLOF for QEMU -- boot code.
+ * Initial entry point
+ */
+
+#include <xvect.h>
+#include <cpu.h>
+#include <macros.h>
+
+ /* qemu entry:
+ *
+ * __start loaded at 0x100
+ *
+ * CPU 0 starts at 0 with GPR3 pointing to the flat devtree
+ *
+ * All other CPUs are held in stopped state by qemu and are
+ * started via RTAS
+ */
+ .text
+ .globl __start
+__start:
+ b _start
+ .long 0xDEADBEE0
+ .long 0x0 /* size */
+ .long 0x0 /* crc */
+ .long relTag - __start
+
+ /* Some exception vectors
+ *
+ * FIXME: Also need 0280, 0380, 0f20, etc.
+ */
+
+ .irp i, 0x0100,0x0180,0x0200,0x0280,0x0300,0x0380,0x0400,0x0500, \
+ 0x0600,0x0700,0x0800,0x0900,0x0a00,0x0b00,0x0c00,0x0d00, \
+ 0x0e00,0x0f00,0x1000,0x1100,0x1200,0x1300,0x1400,0x1500, \
+ 0x1600,0x1700, \
+ 0x1800,0x1900,0x1a00,0x1b00,0x1c00,0x1d00,0x1e00,0x1f00, \
+ 0x2000,0x2100,0x2200,0x2300,0x2400,0x2500,0x2600,0x2700, \
+ 0x2800,0x2900,0x2a00,0x2b00,0x2c00,0x2d00,0x2e00
+ . = \i
+
+ /* enable this if you get exceptions before the console works */
+ /* this will allow using the hardware debugger to see where */
+ /* it traps, and with what register values etc. */
+ // b $
+
+ mtsprg 0,r0
+ mfctr r0
+ mtsprg 2,r0
+ mflr r0
+// 10
+ mtsprg 3,r0
+ ld r0, (\i + 0x60)(0)
+ mtctr r0
+ li r0, \i + 0x100
+// 20
+ bctr
+
+ . = \i + 0x60
+ .quad intHandler2C
+ .endr
+
+ . = XVECT_M_HANDLER - 0x100
+ .quad 0x00
+ .text
+
+ /* Here's the startup code for the master CPU */
+ .org 0x4000 - 0x100
+_start:
+ /* Save device-tree pointer */
+ mr r31,r3
+
+ /* Switch to 64-bit mode with 64-bit exceptions */
+#define MSR_SF_LG 63 /* Enable 64 bit mode */
+#define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */
+#define __MASK(X) (1<<(X))
+#define MSR_SF __MASK(MSR_SF_LG) /* Enable 64 bit mode */
+#define MSR_ISF __MASK(MSR_ISF_LG) /* Interrupt 64b mode */
+ mfmsr r11 /* grab the current MSR */
+ li r12,(MSR_SF | MSR_ISF)@highest
+ sldi r12,r12,48
+ or r11,r11,r12
+ mtmsrd r11
+ isync
+
+ /* Early greet */
+ li r3,10
+ bl putc
+ li r3,13
+ bl putc
+ li r3,10
+ bl putc
+ li r3,'S'
+ bl putc
+
+ li r3,'L'
+ bl putc
+ li r3,'O'
+ bl putc
+ li r3,'F'
+ bl putc
+
+ bl print_version
+
+ /* go! */
+ li r3,__startC@l
+ mtctr r3
+ bctrl
+
+ /* write a character to the HV console */
+putc: sldi r6,r3,(24+32)
+ li r3,0x58
+ li r4,0
+ li r5,1
+ .long 0x44000022
+ blr
+
+relTag:
+ .ascii RELEASE
+ .ascii "\0"
+ .align 2
+
+C_ENTRY(proceedInterrupt)
+
+ ld r3,exception_stack_frame@got(r2)
+ ld r1,0(r3)
+
+ .irp i, 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, \
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, \
+ 27, 28, 29, 30, 31
+ ld r\i, 0x30+\i*8 (r1)
+ .endr
+
+ ld r14,0x138(r1);
+ mtsrr0 r14
+
+ ld r14,0x140(r1);
+ mtsrr1 r14
+
+ ld r14,0x148(r1);
+ mtcr r14
+
+ ld 0,XVECT_M_HANDLER(0)
+ mtctr 0
+
+ ld r0,0x30(r1); # restore vector number
+ ld r1,0x38(r1);
+
+ bctr
+
+intHandler2C:
+ mtctr r1 # save old stack pointer
+ lis r1,0x4
+ stdu r1, -0x160(r1)
+ .irp i, 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, \
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, \
+ 27, 28, 29, 30, 31
+ std r\i, 0x30+\i*8 (r1)
+ .endr
+
+ std r0,0x30(r1); # save vector number
+
+ mfctr r14
+ std r14,0x38(r1); # save old r1
+
+ mfsrr0 r14
+ std r14,0x138(r1);
+
+ mfsrr1 r14
+ std r14,0x140(r1);
+
+ mfcr r14
+ std r14,0x148(r1);
+
+ mfxer r14
+ std r14,0x150(r1);
+
+ bl toc_init
+
+ ld r3,exception_stack_frame@got(r2)
+ std r1,0(r3)
+
+
+ mr r3,r0
+ bl .c_interrupt
+
+ ld r14,0x138(r1);
+ mtsrr0 r14
+
+ ld r14,0x140(r1);
+ mtsrr1 r14
+
+ ld r14,0x148(r1);
+ mtcr r14
+
+ ld r14,0x150(r1);
+ mtxer r14
+
+
+ .irp i, 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, \
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, \
+ 27, 28, 29, 30, 31
+ ld r\i, 0x30+\i*8 (r1)
+ .endr
+
+ ld r1,0x38(r1);
+
+ mfsprg r0,2
+ mtctr r0
+ mfsprg r0,3
+ mtlr r0
+ mfsprg r0,0
+ rfid
+
+/* Set exception handler for given exception vector.
+ r3: exception vector offset
+ r4: exception handler
+*/
+ .globl .set_exception
+.set_exception:
+ .globl set_exception
+set_exception:
+ ld r4,0x0(r4)
+ .globl .set_exception_asm
+.set_exception_asm:
+ .globl set_exception_asm
+set_exception_asm:
+ std r4, 0x60(r3) # fixme diff 1f - 0b
+ blr
diff --git a/qemu/roms/SLOF/board-qemu/llfw/version.S b/qemu/roms/SLOF/board-qemu/llfw/version.S
new file mode 100644
index 000000000..f0a778abe
--- /dev/null
+++ b/qemu/roms/SLOF/board-qemu/llfw/version.S
@@ -0,0 +1,42 @@
+/******************************************************************************
+ * Copyright (c) 2010, 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
+ *****************************************************************************/
+
+/*
+ * Print version information
+ * This code is in a separate file so that it can be easily compiled during
+ * each new build (for refreshing the build date).
+ */
+
+#include "termctrl.h"
+#include <product.h>
+
+.global print_version
+print_version:
+ mflr r4
+ bl 0f
+ .ascii TERM_CTRL_RESET
+ .ascii TERM_CTRL_CRSOFF
+ .ascii " **********************************************************************"
+ .ascii "\r\n"
+ .ascii TERM_CTRL_BRIGHT
+ .ascii PRODUCT_NAME
+ .ascii " Starting\r\n"
+ .ascii TERM_CTRL_RESET
+ .ascii " Build Date = ", __DATE__, " ", __TIME__
+ .ascii "\r\n"
+ .ascii " FW Version = " , RELEASE
+ .ascii "\r\n\0"
+ .align 2
+0:
+ mflr r3
+ mtlr r4
+ b io_print