summaryrefslogtreecommitdiffstats
path: root/qemu/roms/SLOF/llfw
diff options
context:
space:
mode:
authorYang Zhang <yang.z.zhang@intel.com>2015-08-28 09:58:54 +0800
committerYang Zhang <yang.z.zhang@intel.com>2015-09-01 12:44:00 +0800
commite44e3482bdb4d0ebde2d8b41830ac2cdb07948fb (patch)
tree66b09f592c55df2878107a468a91d21506104d3f /qemu/roms/SLOF/llfw
parent9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (diff)
Add qemu 2.4.0
Change-Id: Ic99cbad4b61f8b127b7dc74d04576c0bcbaaf4f5 Signed-off-by: Yang Zhang <yang.z.zhang@intel.com>
Diffstat (limited to 'qemu/roms/SLOF/llfw')
-rw-r--r--qemu/roms/SLOF/llfw/boot_abort.S95
-rw-r--r--qemu/roms/SLOF/llfw/boot_abort.h37
-rw-r--r--qemu/roms/SLOF/llfw/clib/Makefile.inc42
-rw-r--r--qemu/roms/SLOF/llfw/clib/iolib.c47
-rw-r--r--qemu/roms/SLOF/llfw/clib/iolib.h26
-rw-r--r--qemu/roms/SLOF/llfw/io_generic/Makefile.inc38
-rw-r--r--qemu/roms/SLOF/llfw/io_generic/io_generic.S129
-rw-r--r--qemu/roms/SLOF/llfw/nvramlog.S350
-rw-r--r--qemu/roms/SLOF/llfw/romfs.S362
-rw-r--r--qemu/roms/SLOF/llfw/romfs_wrap.c22
10 files changed, 1148 insertions, 0 deletions
diff --git a/qemu/roms/SLOF/llfw/boot_abort.S b/qemu/roms/SLOF/llfw/boot_abort.S
new file mode 100644
index 000000000..996bdd78a
--- /dev/null
+++ b/qemu/roms/SLOF/llfw/boot_abort.S
@@ -0,0 +1,95 @@
+/******************************************************************************
+ * 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 "termctrl.h"
+#include "boot_abort.h"
+#include <cpu.h>
+
+#define MSG_LOOK_HDR TERM_CTRL_BRIGHT, TERM_BG_RED, TERM_FG_WHITE
+
+ASM_ENTRY(msg_e_crc)
+ .ascii MSG_LOOK_HDR
+ .ascii "\n\r\n\rE1001 - Boot ROM CRC failure\n\r"
+ .ascii TERM_CTRL_RESET, "\0"
+ .align 2
+
+ASM_ENTRY(msg_e_nomem)
+ .ascii MSG_LOOK_HDR
+ .ascii "\n\r\n\rE1002 - Memory could not be initialized\n\r"
+ .ascii TERM_CTRL_RESET, "\0"
+ .align 2
+
+ASM_ENTRY(msg_e_nofile)
+ .ascii MSG_LOOK_HDR
+ .ascii "\n\r\n\rE1003 - Firmware image incomplete"
+ .ascii TERM_CTRL_RESET
+ .ascii "\n\r internal FLS1-FFS-0.\0"
+ .align 2
+
+ASM_ENTRY(msg_e_ierror)
+ .ascii MSG_LOOK_HDR
+ .ascii "\n\r\n\rE1004 - Unspecified Internal Firmware Error"
+ .ascii TERM_CTRL_RESET
+ .ascii "\n\r internal FLSX-SE-0.\0"
+ .align 2
+
+/* E1005 : used in memory init code */
+
+/*****************************************************************************
+ * Boot Abort Handler
+ *
+ * Input:
+ * R3 - capability informatin (i/o etc.)
+ * R4 - handling suggestion
+ * R5 - error string reference
+ * R6 - error number
+ *
+ * Return:
+ * if possible input to H8 and NVRAM log and console , then reboot/halt
+ *
+ * Input definitions:
+ *
+ * R3 bits: 63 (h8/console possible) ... add more
+ * R4 bits: 63 (do not attempt reboot)
+ * R5 reference to error message string
+ * R6 32-bit error enumerator
+ *
+ ******************************************************************************/
+ASM_ENTRY(boot_abort)
+ /* save arguments */
+ mr r31, r3
+ mr r30, r4
+ mr r29, r5
+ mr r28, r6
+
+ /* check if i/o is possible, if yes then print message */
+ li r10, ABORT_CANIO
+ andi. r3, r31, r10
+ bne abort_noio
+
+ /* use i/o ..., first print reference message */
+ /* then add internal number if != 0 */
+ mr r3, r29
+ mfspr r4, HSPRG0 /* get runbase */
+ or r3, r3, r4
+ bl io_print
+ mr r3, r28
+ li r28, 0
+ cmpd r3, r28
+ beq 0f
+ bl io_printhex32
+0:
+
+ abort_noio:
+ b $ // FIXME
+ /* never reached */
+
diff --git a/qemu/roms/SLOF/llfw/boot_abort.h b/qemu/roms/SLOF/llfw/boot_abort.h
new file mode 100644
index 000000000..b7082063c
--- /dev/null
+++ b/qemu/roms/SLOF/llfw/boot_abort.h
@@ -0,0 +1,37 @@
+/******************************************************************************
+ * 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 BOOT_ABORT_H
+#define BOOT_ABORT_H
+
+/* boot abort function suitable for assembly */
+#define BOOT_ABORT(cap, action, msg, numhint) \
+ li r3, cap; \
+ li r4, action; \
+ LOAD32(r5, msg); \
+ LOAD32(r6, numhint); \
+ bl boot_abort
+
+/* boot abort function suitable called from c (takes r3 as hint) */
+#define BOOT_ABORT_R3HINT(cap, action, msg) \
+ mr r6, r3; \
+ li r3, cap; \
+ li r4, action; \
+ LOAD32(r5, msg); \
+ bl boot_abort
+
+#define ABORT_CANIO (1 << 0)
+#define ABORT_NOIO (1 << 1)
+
+#define ALTBOOT (1 << 0)
+#define HALT (1 << 1)
+
+#endif
diff --git a/qemu/roms/SLOF/llfw/clib/Makefile.inc b/qemu/roms/SLOF/llfw/clib/Makefile.inc
new file mode 100644
index 000000000..70037989e
--- /dev/null
+++ b/qemu/roms/SLOF/llfw/clib/Makefile.inc
@@ -0,0 +1,42 @@
+# *****************************************************************************
+# * 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 ../../make.rules
+
+CFLAGS_COMLIB = -pedantic -std=gnu99 -O0
+ASFLAGS_COMLIB =
+
+
+COMLIBDIR = $(LLFWCMNDIR)/clib
+
+COMLIB_SRC_ASM =
+COMLIB_SRC_C = iolib.c
+
+COMLIB_SRCS = $(COMLIB_SRC_ASM:%=$(COMLIBDIR)/%) \
+ $(COMLIB_SRC_C:%=$(COMLIBDIR)/%)
+COMLIB_OBJ_ASM = $(COMLIB_SRC_ASM:%.S=%.o)
+COMLIB_OBJ_C = $(COMLIB_SRC_C:%.c=%.o)
+
+
+comlib.o: $(COMLIB_OBJ_C) $(COMLIB_OBJ_ASM)
+ $(LD) $(LDFLAGS) $^ -o $@ -r
+
+%.o: $(LLFWCMNDIR)/clib/%.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_COMLIB) -c $< -o $@
+
+%.o: $(LLFWCMNDIR)/clib/%.S
+ $(CC) $(CPPFLAGS) $(ASFLAGS) $(ASFLAGS_COMLIB) -c $< -o $@
+
+LLFW_CLEAN_TARGETS += clean_clib
+.PHONY : clean_clib
+clean_clib:
+ rm -f $(COMLIB_OBJ_C) $(COMLIB_OBJ_ASM) comlib.o
diff --git a/qemu/roms/SLOF/llfw/clib/iolib.c b/qemu/roms/SLOF/llfw/clib/iolib.c
new file mode 100644
index 000000000..7f14b512d
--- /dev/null
+++ b/qemu/roms/SLOF/llfw/clib/iolib.c
@@ -0,0 +1,47 @@
+/******************************************************************************
+ * 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 <stdint.h>
+#include <stddef.h>
+#include <unistd.h>
+#include "iolib.h"
+
+void uart_send_byte(unsigned char b)
+{
+ asm volatile ("":::"3","4","5","6","7");
+ io_putchar(b);
+}
+
+/**
+ * Standard write function for the libc.
+ *
+ * @param fd file descriptor (should always be 1 or 2)
+ * @param buf pointer to the array with the output characters
+ * @param count number of bytes to be written
+ * @return the number of bytes that have been written successfully
+ */
+ssize_t write(int fd, const void *buf, size_t count)
+{
+ size_t i;
+ char *ptr = (char *)buf;
+
+ if (fd != 1 && fd != 2)
+ return 0;
+
+ for (i = 0; i < count; i++) {
+ if (*ptr == '\n')
+ uart_send_byte('\r');
+ uart_send_byte(*ptr++);
+ }
+
+ return i;
+}
diff --git a/qemu/roms/SLOF/llfw/clib/iolib.h b/qemu/roms/SLOF/llfw/clib/iolib.h
new file mode 100644
index 000000000..91450058c
--- /dev/null
+++ b/qemu/roms/SLOF/llfw/clib/iolib.h
@@ -0,0 +1,26 @@
+/******************************************************************************
+ * 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 IOLIB_H
+#define IOLIB_H
+
+#include <stdint.h>
+
+#define addr_t volatile unsigned int
+#define addr8_t volatile unsigned char
+
+extern void halt_sys (unsigned int);
+
+extern void uart_send_byte(unsigned char b);
+extern void io_putchar(unsigned char);
+
+#endif
diff --git a/qemu/roms/SLOF/llfw/io_generic/Makefile.inc b/qemu/roms/SLOF/llfw/io_generic/Makefile.inc
new file mode 100644
index 000000000..b6607252f
--- /dev/null
+++ b/qemu/roms/SLOF/llfw/io_generic/Makefile.inc
@@ -0,0 +1,38 @@
+# *****************************************************************************
+# * 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
+# ****************************************************************************/
+
+IOGENERICDIR = $(LLFWCMNDIR)/io_generic
+
+IO_GENERIC_SRC_ASM = io_generic.S
+IO_GENERIC_SRC_C =
+
+IO_GENERIC_SRCS = $(IO_GENERIC_SRC_ASM:%=$(IOGENERICDIR)/%) \
+ $(IO_GENERIC_SRC_C:%=$(IOGENERICDIR)/%)
+IO_GENERIC_OBJ_ASM = $(IO_GENERIC_SRC_ASM:%.S=%.o)
+IO_GENERIC_OBJ_C = $(IO_GENERIC_SRC_C:%.c=%.o)
+
+
+io_generic_lib.o: $(IO_GENERIC_OBJ_ASM) $(IO_GENERIC_OBJ_C)
+ $(LD) $(LDFLAGS) $^ -o $@ -r
+
+
+%.o: $(IOGENERICDIR)/%.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
+
+%.o: $(IOGENERICDIR)/%.S
+ $(CC) $(CPPFLAGS) $(ASFLAGS) -c $< -o $@
+
+
+LLFW_CLEAN_TARGETS += clean_io_generic
+.PHONY : clean_io_generic
+clean_io_generic:
+ rm -f $(IO_GENERIC_OBJ_C) $(IO_GENERIC_OBJ_ASM) io_generic_lib.o
diff --git a/qemu/roms/SLOF/llfw/io_generic/io_generic.S b/qemu/roms/SLOF/llfw/io_generic/io_generic.S
new file mode 100644
index 000000000..9c1db41a1
--- /dev/null
+++ b/qemu/roms/SLOF/llfw/io_generic/io_generic.S
@@ -0,0 +1,129 @@
+/******************************************************************************
+ * 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 "calculatecrc.h"
+#include "calculatecrc.h"
+
+ .text
+
+/****************************************************************************
+ * prints a 0-terminated string to serial console
+ *
+ * Input:
+ * R3 - pointer to string in memory
+ *
+ * Returns: -
+ *
+ * Modifies Registers:
+ * R3, R4, R5, R6, R7, R8, R9
+ ****************************************************************************/
+ASM_ENTRY(io_print)
+ mflr r8
+ mr r9, r3
+
+0:
+ lbz r3, 0(r9)
+ cmpwi r3, 0
+ beq 1f
+ bl io_putchar
+ addi r9, r9, 1
+ b 0b
+1:
+ mtlr r8
+ blr
+
+/****************************************************************************
+ * prints Hex integer to the UART and the NVRAM (using board io_putchar)
+ *
+ * Input:
+ * R3 - integer to print
+ *
+ * Returns: -
+ *
+ * Modifies Registers:
+ * R3, R4, R5, R6, R7, R8, R9
+ ****************************************************************************/
+#define _io_gen_print_nib(reg, src, shift) \
+ srdi reg, src, shift; \
+ andi. reg, reg, 0x0F; \
+ cmpwi reg, 0x0A; \
+ blt 0f; \
+ addi reg, reg, ('A'-'0'-10); \
+0:; \
+ addi reg, reg, '0'; \
+ bl io_putchar
+
+ASM_ENTRY(io_printhex64)
+ mflr r8
+ mr r9, r3
+
+_io_printhex64:
+ _io_gen_print_nib(r3, r9, 60)
+ _io_gen_print_nib(r3, r9, 56)
+ _io_gen_print_nib(r3, r9, 52)
+ _io_gen_print_nib(r3, r9, 48)
+ _io_gen_print_nib(r3, r9, 44)
+ _io_gen_print_nib(r3, r9, 40)
+ _io_gen_print_nib(r3, r9, 36)
+ _io_gen_print_nib(r3, r9, 32)
+_io_printhex32:
+ _io_gen_print_nib(r3, r9, 28)
+ _io_gen_print_nib(r3, r9, 24)
+ _io_gen_print_nib(r3, r9, 20)
+ _io_gen_print_nib(r3, r9, 16)
+_io_printhex16:
+ _io_gen_print_nib(r3, r9, 12)
+ _io_gen_print_nib(r3, r9, 8)
+_io_printhex8:
+ _io_gen_print_nib(r3, r9, 4)
+ _io_gen_print_nib(r3, r9, 0)
+
+ mtlr r8
+ blr
+
+ASM_ENTRY(io_printhex32)
+ mflr r8
+ mr r9, r3
+ b _io_printhex32
+
+ASM_ENTRY(io_printhex16)
+ mflr r8
+ mr r9, r3
+ b _io_printhex16
+
+ASM_ENTRY(io_printhex8)
+ mflr r8
+ mr r9, r3
+ b _io_printhex8
+
+
+/****************************************************************************
+ * print the address and its contents as 64-bit hex values
+ *
+ * Input:
+ * R3 - Address to read from
+ *
+ * Returns: -
+ *
+ * Modifies Registers:
+ * R3, R4, R5, R6, R7, R8, R9, R10
+ ****************************************************************************/
+#if 0 /* currently unused */
+ASM_ENTRY(io_dump)
+ mflr r10
+ bl io_printhex64
+ li r3,':'
+ bl io_putchar
+ ld r9,0(r9)
+ mr r8,r10
+ b _io_printhex64
+#endif
diff --git a/qemu/roms/SLOF/llfw/nvramlog.S b/qemu/roms/SLOF/llfw/nvramlog.S
new file mode 100644
index 000000000..3ad2de754
--- /dev/null
+++ b/qemu/roms/SLOF/llfw/nvramlog.S
@@ -0,0 +1,350 @@
+/******************************************************************************
+ * 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 <nvramlog.h>
+#include <southbridge.h>
+#include <calculatecrc.h>
+
+#if !defined(DISABLE_NVRAM) && !defined(RTAS_NVRAM)
+
+// detect overflow: if(a<b) return a else return 0
+#define NVRAM_LOG_DATA_OVERFLOW( a, b) \
+ cmpd 7, a, b; \
+ blt+ 7, 0f; \
+ li a, 0; \
+ 0:
+
+// get Pointer(pointer) to next byte in NVRAM data section
+// and size of this data sechtion (modulo)
+// modifies register pointer, modulo
+#define NVRAM_POINTER_DATASIZE_BE0(pointer, modulo, address) \
+ LOAD64( modulo, LLFW_LOG_BE0_LENGTH); \
+ lwz pointer, LLFW_LOG_POS_POINTER(address); \
+ sldi modulo, modulo, 4; \
+ addi modulo, modulo,-LLFW_LOG_BE0_DATA_OFFSET
+#define NVRAM_POINTER_DATASIZE_BE1(pointer, modulo, address) \
+ LOAD64( modulo, LLFW_LOG_BE1_LENGTH); \
+ lwz pointer, LLFW_LOG_POS_POINTER(address); \
+ sldi modulo, modulo, 4; \
+ addi modulo, modulo,-LLFW_LOG_BE1_DATA_OFFSET
+
+/****************************************************************************
+ * checkLogHeaderData
+ * compare the fixed values in the header if any change was done since
+ * last initialisation.
+ * Flags are not checked!
+ *
+ * Retrun 0 if no manimulation was found 1 else
+ *
+ * input:
+ * r3 - NVRAM Base Address
+ *
+ * output:
+ * r3 - status: 0 = ok, 1 = corrupt
+ * r4 - NVRAM Base Address
+ *
+ ***************************************************************************/
+ASM_ENTRY(checkLogHeaderData)
+ li r4, 0 // init error flag
+ lbz r5, 0(r3) // check signature
+ addi r5, r5, -LLFW_LOG_BE0_SIGNATURE
+ add r4, r4, r5
+
+ lhz r5, LLFW_LOG_POS_LENGTH(r3) // check length
+ addi r5, r5, -LLFW_LOG_BE0_LENGTH
+ add r4, r4, r5
+
+ lwz r5, LLFW_LOG_POS_NAME(r3) // check name prefix
+ LOAD64( r6, LLFW_LOG_BE0_NAME_PREFIX)
+ subf r5, r6, r5
+ add r4, r4, r5
+
+ ld r5, (LLFW_LOG_POS_NAME+4)(r3) // check name
+ LOAD64( r6, LLFW_LOG_BE0_NAME)
+ subf r5, r6, r5
+ add r4, r4, r5
+
+ lhz r5, LLFW_LOG_POS_DATA_OFFSET(r3) //check data offset
+ addi r5, r5, -LLFW_LOG_BE0_DATA_OFFSET
+ add r4, r4, r5
+
+ lhz r5, LLFW_LOG_POS_FLAGS(r3) //check flags
+ addi r5, r5, -LLFW_LOG_BE0_FLAGS
+ add r4, r4, r5
+
+ cmpldi 7, r4, 0
+ beq+ 7, 0f
+ li r4, 1
+0:
+ mr r5, r3
+ mr r3, r4
+ mr r4, r5
+ blr
+/*****************************************************************************
+ * checkLogPartition: check Partition Header entries and Checksum
+ * check also the NVRAM-Log-Partition CRC
+ * if Partition is not ok set the following bits to 1
+ * bit 1: if Partiton Header Checksum is corrupt
+ * bit 2: if CRC is corrupt
+ * bit 3: if Header entries are corrupt
+ *
+ * input:
+ * r3 - NVRAM log address (BASE + NVRAM_LOG_OFFSET)
+ *
+ * output:
+ * r3 - CRC status
+ * r4 - NVRAM log address
+ *
+ * Modifies Register: R3, R4, R5, R6, R7, R8, R9
+ ****************************************************************************/
+ASM_ENTRY(.checkLogPartition)
+ mflr r8
+ mr r4, r3 // emulate "bl updateCRC_NVRAM"
+ li r3, 0 // with successful CRC check
+ li r7, 0
+ cmpwi 7, r3, 0
+ beq+ 7, 0f
+ li r7, 2
+0:
+ mr r3, r4
+ bl .calPartitionHeaderChecksum // r3=checksum, r4=NVARM addr
+ lbz r6, LLFW_LOG_POS_CHECKSUM(r4)
+ cmpw 7, r3, r6
+ beq+ 7, 0f // cal checksum must eq checksum
+ ori r7, r7, 1
+0:
+ cmpwi 7, r3, 0
+ bne+ 7, 0f
+ ori r7, r7, 1 // 0 as checksum is invalid
+0:
+ mr r3, r4
+ bl checkLogHeaderData
+ cmpdi 7, r3, 0
+ beq+ 7, 0f
+ ori r7, r7, 4
+0:
+ mr r3, r7
+ mtlr r8
+ blr
+/*****************************************************************************
+ * checkinitLog: check the NVRAM Log Partition Header
+ * initialize the NVRAM if the Header was modified
+ *
+ * input:
+ * r3 - NVRAM BASE address
+ *
+ * output:
+ * r3 - 0 = check ok, no new header written
+ * r3 - 1 = check not ok, header and NVRAM initialized
+ * r4 - NVRAM log address
+ *
+ * Modifies Register: R3, R4, R5, R6, R7, r8, r9
+ ****************************************************************************/
+// init is done if checkLogPartiton returns not 0 (= check failed)
+ASM_ENTRY(.checkinitLog)
+ASM_ENTRY(checkinitLog)
+ mflr r9
+ bl .checkLogPartition //r3..r8, r4_out = r3_in
+ mtlr r9
+
+ cmpwi 7, r3, 0
+ mr r3, r4 // r3=NVRAM_LOG address
+ bne- 7, .initLog // if header is not ok, init header
+ li r3, 0
+ blr // header OK, return 0
+
+
+/* this is basically just a copy of .initLog
+ registers used: r3, r4, r5, r6, r7, r9*/
+init_log_2nd_be:
+ mflr r9
+ li r6, LLFW_LOG_BE0_LENGTH
+ mulli r6, r6, 0x10
+ add r6, r7, r6
+ li r5, LLFW_LOG_BE1_SIGNATURE
+ li r4, LLFW_LOG_BE1_LENGTH
+ stb r5, 0(r6)
+ sth r4, LLFW_LOG_POS_LENGTH(r6)
+ li r5, LLFW_LOG_BE1_DATA_OFFSET
+ li r4, LLFW_LOG_BE1_FLAGS
+ sth r5, LLFW_LOG_POS_DATA_OFFSET(r6)
+ sth r4, LLFW_LOG_POS_FLAGS(r6)
+ li r5, 1
+
+ LOAD32( r4, LLFW_LOG_BE1_NAME_PREFIX)
+ stw r5, LLFW_LOG_POS_POINTER(r6)
+ stw r4, (LLFW_LOG_POS_NAME+0x00)(r6)
+ LOAD64( r5, LLFW_LOG_BE1_NAME)
+ std r5, (LLFW_LOG_POS_NAME+0x04)(r6)
+ mr r3, r6
+ bl .calPartitionHeaderChecksum
+ stb r3, LLFW_LOG_POS_CHECKSUM(r6)
+ mtlr r9
+ blr
+/*****************************************************************************
+ * initLog: initialize the NVRAM with 0
+ * write a new NVRAM Log-Partition-Header
+ *
+ * input:
+ * r3 - NVRAM BASE address
+ *
+ * output:
+ * r3 - 0 = check ok, no new header written
+ * r3 - 1 = check not ok, header and NVRAM initialized
+ * r4 - NVRAM log address
+ *
+ * Modifies Register: R3, R4, R5, R6, R7, r8, r9
+ ****************************************************************************/
+ASM_ENTRY(.initLog)
+ mflr r8
+ mr r7, r3
+
+ bl clearNVRAM
+0:
+ li r5, LLFW_LOG_BE0_SIGNATURE
+ li r4, LLFW_LOG_BE0_LENGTH
+ stb r5, 0(r7)
+ sth r4, LLFW_LOG_POS_LENGTH(r7)
+ li r5, LLFW_LOG_BE0_DATA_OFFSET
+ li r4, LLFW_LOG_BE0_FLAGS
+ sth r5, LLFW_LOG_POS_DATA_OFFSET(r7)
+ sth r4, LLFW_LOG_POS_FLAGS(r7)
+ li r5, 1
+
+ LOAD32( r4, LLFW_LOG_BE0_NAME_PREFIX)
+ stw r5, LLFW_LOG_POS_POINTER(r7)
+ stw r4, (LLFW_LOG_POS_NAME+0x00)(r7)
+ LOAD64( r5, LLFW_LOG_BE0_NAME)
+ std r5, (LLFW_LOG_POS_NAME+0x04)(r7)
+ bl .calPartitionHeaderChecksum
+ stb r3, LLFW_LOG_POS_CHECKSUM(r7)
+ bl init_log_2nd_be // create a second log partition for BE1
+ mr r4, r7
+ li r3, 1
+ mtlr r8
+ blr
+/*****************************************************************************
+ * clearNVRAM: set all not used NVRAM memory to zero
+ *
+ *
+ * input:
+ * R3 - NVRAM BASE ADDRESS
+ *
+ * output:
+ * R3 - NVARM END ADDRESS
+ *
+ * Modifies Register: r4, r5
+ ****************************************************************************/
+ASM_ENTRY(clearNVRAM)
+ LOAD64( r4, NVRAM_LENGTH)
+ srdi r4, r4, 3
+ mtctr r4
+ li r5, 0x0
+ LOAD64( r4, NVRAM_EMPTY_PATTERN)
+0:
+ stdx r4, r3,r5
+ addi r5, r5, 8
+ bdnz+ 0b
+ blr
+/*****************************************************************************
+ * writeNVRAMbyte: write next log into NVRAM
+ *
+ *
+ * input:
+ * R3 - byte to be written
+ * R4 - NVRAM Base Address
+ *
+ * output:
+ * R3 - byte that was written
+ * R4 - NVRAM Base Address
+ *
+ * Modifies Register: R3, R4, R5, R6
+ ****************************************************************************/
+ASM_ENTRY(.writeNVRAMbyte)
+ENTRY(writeLogByte)
+ NVRAM_POINTER_DATASIZE_BE0( r5, r6, r4) // get pointer,size of data
+ NVRAM_LOG_DATA_OVERFLOW( r5, r6) // check for overflow
+ addi r5, r5, 1 // increment pointer
+ stw r5, LLFW_LOG_POS_POINTER(r4) // store pointer
+ addi r5, r5, -1 // restore old pointer
+ add r6, r4, r5 // byte address in data section
+
+ stb r3, LLFW_LOG_BE0_DATA_OFFSET(r6)
+ blr
+
+/*****************************************************************************
+ * writeNVRAMbyte: write next log into NVRAM
+ *
+ *
+ * input:
+ * R3 - byte to be written
+ * R4 - NVRAM Base Address
+ *
+ * output:
+ * R3 - byte that was written
+ * R4 - NVRAM Base Address
+ *
+ * Modifies Register: R3, R4, R5, R6
+ ****************************************************************************/
+ENTRY(writeLogByteBE1)
+ li r6, LLFW_LOG_BE0_LENGTH
+ mulli r6, r6, 0x10
+ add r4, r6, r4
+ NVRAM_POINTER_DATASIZE_BE1( r5, r6, r4) // get pointer,size of data
+ NVRAM_LOG_DATA_OVERFLOW( r5, r6) // check for overflow
+ addi r5, r5, 1 // increment pointer
+ stw r5, LLFW_LOG_POS_POINTER(r4) // store pointer
+ addi r5, r5, -1 // restore old pointer
+ add r6, r4, r5 // byte address in data section
+
+ stb r3, LLFW_LOG_BE1_DATA_OFFSET(r6)
+ blr
+
+/*****************************************************************************
+ * calPartitionHeaderChecksum: calculate the Checksum of the
+ * Partition Header as described in ....
+ *
+ * input: r3 - NVRAM BASE adresse
+ *
+ * output: R3 - the calculated checksum as 8 bit value
+ * R4 - NVRAM log address
+ *
+ * Modifies Register: R3, R4, R5, R6
+ ****************************************************************************/
+ASM_ENTRY(.calPartitionHeaderChecksum)
+ mr r6, r3
+ lbz r3,0(r6) // load first byte
+ LOAD64( r4, LLFW_LOG_POS_LENGTH) // load position of 3rd byte
+.L6:
+ lbzx r5, r4, r6 // r5 nexed byte
+ addi r4, r4, 1 // r4++ (index)
+ add r5, r5, r3 // r5 new sum =sum + nexed byte
+ rldicl r5, r5, 0, 56
+ cmpld 7, r5, r3
+ cmpldi 6, r4, LLFW_LOG_POS_DATA_OFFSET
+ bge+ 7,.L5 // if new sum > sum
+ addi r5, r5, 1 // new sum ++
+ rldicl r5, r5, 0, 56
+.L5:
+ mr r3,r5 // sum = new sum
+ blt+ 6,.L6
+
+ mr r4, r6
+ blr
+
+#else /* defined(DISABLE_NVRAM) || defined(RTAS_NVRAM) */
+
+ASM_ENTRY(.writeNVRAMbyte)
+ ENTRY(writeLogByte)
+ blr
+
+#endif
diff --git a/qemu/roms/SLOF/llfw/romfs.S b/qemu/roms/SLOF/llfw/romfs.S
new file mode 100644
index 000000000..325f79e5e
--- /dev/null
+++ b/qemu/roms/SLOF/llfw/romfs.S
@@ -0,0 +1,362 @@
+/******************************************************************************
+ * 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 "romfs.h"
+
+/*******************************************************************
+ * Wrapper for romfs_lookup.
+ *
+ * Input:
+ * R3 = address of filename string
+ * R4 = address of struct romfs_t
+ * 0: file size (return)
+ * 8: flags (return)
+ * 10: fileaddr (return and input: tells if first search)
+ * 18: nextfile (return)
+ * 20: namep (return)
+ *
+ * Find File Procedure
+ * - set filename and rombase, on return 0 file properties are stored
+ * in romfs_t else struct not valid
+ *
+ * Listing procedure
+ * - clear romfs_t (important!)
+ * - set filename = NULL and rombase and call returns first file
+ * with properties in romfs_t including next-file pointer
+ * - if nextpointer is non-zero then just the next file is returned
+ *
+ * Returns:
+ * <Success>:
+ * R3 = 0
+ * romfs_t is updated
+ * <FileNotFound>:
+ * R3 = 1
+ * romfs_t not touched
+ *
+ * Potentially modifies the following registers:
+ *
+
+ Example usage from C:
+
+ int list_bootrom()
+ {
+ struct romfs_t rfs;
+ int i;
+
+ printf("Build: "__TIME__" "__DATE__" \n");
+
+ i = 0;
+ memset((void*) &rfs, 0, sizeof(struct romfs_t));
+ printf(" No. File Data Size Name\n");
+
+ while (romfs_stat(NULL, &rfs) == 0) {
+ i++;
+ printf(" %02d: %08X %08X %7d %s\n",
+ i, rfs.fileaddr, rfs.datap,
+ rfs.size, rfs.namep);
+ }
+ if (0 == i) {
+ printf("Error in reading ROMFS\n");
+ return 1;
+ }
+ return 0;
+ }
+ *******************************************************************/
+#define RFS_T_SIZE 0x00
+#define RFS_T_FLAGS 0x08
+#define RFS_T_FILEADDR 0x10
+#define RFS_T_NEXT 0x18
+#define RFS_T_NAME 0x20
+#define RFS_T_DATA 0x28
+
+#define RFS_H_NEXT 0x00
+#define RFS_H_SIZE 0x08
+#define RFS_H_FLAGS 0x10
+#define RFS_H_DATA 0x18
+#define RFS_H_NAME 0x20
+
+ENTRY(romfs_stat_file)
+ /* save link register and romfs_t pointer */
+ mflr r15
+ mr r16, r4
+
+ /* if filename R3 is 0 then its a listing request */
+ /* if not then just continue to lookup name */
+ /* save R4 to R8 which is the address of header */
+ li r7, 0
+ cmpd r3, r7
+ beq romfs_list
+ bl romfs_lookup
+ mfsprg r8, 1
+
+ /* if file found then go to romfs_fill_properties */
+ /* else return 1 to caller */
+ cmpwi r3, 0
+ beq romfs_fill_properties
+ b romfs_stat_end
+
+ romfs_list:
+ /* check if fileaddr == 0, in this case its */
+ /* the first search on this handle, so return all */
+ /* info for file at rombase (R8=R4) */
+ ld r6, RFS_T_FILEADDR(r4)
+ mfsprg r8, 1
+ li r7, 0
+ cmpd r7, r6
+ beq romfs_fill_properties
+
+ /* check if next file != 0 by looking into */
+ /* romfs_t, if not then return (next = 0) 1 */
+ li r7, 0
+ ld r4, RFS_T_NEXT(r4)
+ cmpd r7, r4
+ li r3, 1
+ beq romfs_stat_end
+
+ /* now next file is available so move R8 to next */
+ /* file address */
+ mr r8, r4
+
+ romfs_fill_properties:
+ /* set properties in romfs_t takes R8 as address */
+ /* to file header and R16 as address of romfs_t */
+ mfsprg r3, 1
+ std r8, RFS_T_FILEADDR(r16)
+
+ ld r4, RFS_H_NEXT(r8)
+ li r7, 0
+ cmpd r7, r4
+ beq $ + (2 * 4) /* =0 so add no rombase */
+ add r4, r4, r3
+ std r4, RFS_T_NEXT(r16)
+
+ ld r4, RFS_H_SIZE(r8)
+ std r4, RFS_T_SIZE(r16)
+ ld r4, RFS_H_FLAGS(r8)
+ std r4, RFS_T_FLAGS(r16)
+
+ ld r4, RFS_H_DATA(r8)
+ add r4, r4, r3
+ std r4, RFS_T_DATA(r16)
+
+ addi r4, r8, RFS_H_NAME
+ std r4, RFS_T_NAME(r16)
+
+ li r3, 0
+
+ /* restore romfs_t pointer and link register */
+ romfs_stat_end:
+ mr r5, r16
+ mtlr r15
+ blr
+
+/*******************************************************************
+ * Copies the data of file referenced by name string to address
+ * requires root address of filesystem.
+ * FIXME: ignores flags
+ *
+ * Input:
+ * R3 = address of filename string
+ * R4 = ROMBASE
+ * R5 = destination address
+ *
+ * Returns:
+ * <Success>: R3 = 0, R6 = size, <FileNotFound>: R3 = 1
+ * R5 is kept
+ *
+ * Potentially modifies the following registers:
+ * ctr, r15, r16, r17, r18
+ *
+ * Uses the following calls with subsequent register modification:
+ * - romfs_lookup
+ *******************************************************************/
+ASM_ENTRY(romfs_load)
+ mflr r15
+
+ /* save R5 twice */
+ /* lookup file, input regs */
+ /* are already set */
+ /* if not found, just return */
+ mr r16, r5
+ mr r17, r5
+ bl romfs_lookup
+ cmpwi r3, 1
+ bne 0f
+ mtlr r15
+ blr /* abort, not found */
+
+ /* save data size for return */
+ /* found, copy data */
+ /* data size is in R6 */
+0:
+ //mr r3, r6
+ mtctr r6
+ addi r16, r16, -1 /* dest */
+ addi r5, r5, -1 /* source*/
+
+ /* data is expected to be */
+ /* 8 byte aligned */
+ /* copy loop */
+0: lbzu r18, 1(r5)
+ stbu r18, 1(r16)
+ bdnz 0b
+
+ /* restore size, keep padding */
+ /* restore target address */
+ /* return */
+ mr r5, r17
+ mtlr r15
+ blr
+
+/*******************************************************************
+ * looks up a file based on filename
+ *
+ * Input:
+ * R3 = address of filename string
+ * R4 = ROMBASE
+ *
+ * Returns:
+ * <Success>:
+ * R3 = 0
+ * R4 = address of file header
+ * R5 = address of data (real address)
+ * R6 = size of data
+ * R7 = flags for file
+ * <FileNotFound>:
+ * R3 = 1
+ *
+ * Potentially modifies the following registers:
+ * R3, R4, R5, R6, R7, R8, R9
+ *
+ * Uses the following calls with subsequent register modification:
+ * - romfs_namematch
+ *******************************************************************/
+ASM_ENTRY(romfs_lookup)
+ mflr r9
+
+ romfs_lookup_next:
+ /* save current file base */
+ mr r8, r4
+ /* name to look for */
+ mr r10, r3
+ /* name of file */
+ mr r5, r4
+ addi r5, r5, (4 /* elems */ * 8 /* elem-size */)
+ mr r11, r5 /* for namematch */
+ /* compare */
+ bl romfs_namematch
+ cmpwi r12, 1
+ bne romfs_lookup_match
+
+ /* load next pointer */
+ /* check if next is 0 */
+ /* apply root-offset */
+ ld r5, 0(r4)
+ cmpwi r5, 0
+ add r4, r4, r5
+ bne romfs_lookup_next
+ /* last file reached, abort */
+ li r3, 1
+ mtlr r9
+ blr
+
+ /* here the name did match */
+ /* r4 is still usable here and */
+ /* pointing to the initial file */
+ /* load r5 with data ptr */
+ /* load r6 with data size */
+ /* load r7 with flags */
+ /* get abs addr of data */
+ romfs_lookup_match:
+ li r3, 0
+ ld r5, (3 * 8)(r4) /* data */
+ ld r6, (1 * 8)(r4) /* len */
+ ld r7, (2 * 8)(r4) /* flags */
+ add r5, r5, r8
+ mtlr r9
+ blr
+
+/*******************************************************************
+ * compares two strings in memory,
+ * both must be null-terminated and 8-byte aligned
+ *
+ * Input:
+ * R10 = string 1
+ * R11 = string 2
+ *
+ * Returns:
+ * <Match>: R12 = 0 <NoMatch>: R12 = 1
+ *
+ * Potentially modifies the following registers:
+ * R10, R11, r12, r13, r14
+ *******************************************************************/
+romfs_namematch:
+ subi r10, r10, 8
+ subi r11, r11, 8
+
+ /*
+ * load chars as 8byte chunk from current pos, name is
+ * always 8 byte aligned :)
+ */
+ romfs_cmp_loop:
+ ldu r13, 8(r10) /* A */
+ ldu r14, 8(r11) /* B */
+
+ cmpd r13, r14
+ li r12, 1
+ beq 1f
+ blr
+
+1: andi. r14, r14, 0xff
+ bne romfs_cmp_loop
+
+ li r12, 0
+ blr
+
+/*******************************************************************
+ * wrapper for romfs_lookup
+ * this function saves the registers from r13 - r15 on the stack
+ * calls romfs_lookup
+ * restores the saved registers
+ *
+ * the return parameters are copied to (r5) and (r5) has to
+ * be 0x20 big
+ *******************************************************************/
+ENTRY(c_romfs_lookup)
+ stdu r1,-0x50(r1) # allocate space on stack
+
+ mflr r0 # save link register
+ std r0,0x30(r1)
+
+ std r15,0x38(r1) # save r15
+ std r14,0x40(r1) # save r14
+ std r13,0x48(r1) # and r13
+
+ mr r15,r5 # save the pointer for the return value
+
+ bl romfs_lookup # do the thing
+
+ ld r0,0x30(r1) # restore link register
+ mtlr r0
+
+ std r4,0x00(r15) # copy return values
+ std r5,0x08(r15) # to the return pointer
+ std r6,0x10(r15)
+ std r7,0x18(r15)
+
+ ld r13,0x48(r1) # restore registers from stack
+ ld r14,0x40(r1)
+ ld r15,0x38(r1)
+
+ addi r1,r1,0x50 # cleanup stack
+
+ blr
diff --git a/qemu/roms/SLOF/llfw/romfs_wrap.c b/qemu/roms/SLOF/llfw/romfs_wrap.c
new file mode 100644
index 000000000..323d97525
--- /dev/null
+++ b/qemu/roms/SLOF/llfw/romfs_wrap.c
@@ -0,0 +1,22 @@
+/******************************************************************************
+ * 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 <romfs.h>
+
+int romfs_stat(char *filename, struct romfs_t *hnd)
+{
+ asm volatile ("":::"3","4","5","6","7","9","10");
+ asm volatile ("":::"11","12");
+ asm volatile ("":::"13","14","15","16","17","18");
+
+ return romfs_stat_file(filename, hnd);
+}